这是我在java中的mergesort的代码:
public class MergeSort {
public static void mergesort(int[] input) {
int inputSize = input.length;
if(inputSize < 2) {
return;
}
int[] left = new int[inputSize/2];
int[] right = new int[inputSize/2];
int count = 0;
for(int i=0; i < inputSize/2; i++) {
left[i] = input[i];
}
for(int i=inputSize/2; i<inputSize; i++) {
right[count] = input[i];
count++;
}
mergesort(left);
mergesort(right);
merge(left, right, input);
}
public static int[] merge(int[] returnArr, int[] left, int[] right) {
int leftSize = left.length;
int rightSize = right.length;
int i = 0;
int j =0;
int k = 0;
int count = 0;
while(i < leftSize && j < rightSize) {
if(left[i] <= right[j]) {
returnArr[k] = left[i];
i++;
}
else {
returnArr[k] = right[j];
j++;
}
k++;
}
while(i<leftSize) {
returnArr[k] = left[i];
i++;
k++;
}
while(j < rightSize) {
returnArr[k] = right[j];
j++;
k++;
}
for(int x=0; x<returnArr.length; x++) {
System.out.print(returnArr[x]);
}
return returnArr;
}
public static void main(String[] args) {
int[] array = {3,4,6,2,7,1,8,6};
mergesort(array);
}
}
我的问题是我遇到了越界异常。 我使用调试器并发现在mergesort(左)和mergesort(右)完成递归运行之后。
进入合并函数的左右数组分别具有值[3]和[4],这是正确的。
但是当调试器跳转到merge函数时,left有值[3]和right,因为某种原因是长度为2并且值为[3,4]。
这是我的越界异常的来源,虽然我不确定为什么当合并函数第一次运行时,它会改变&#34;右&#34;的值。
答案 0 :(得分:0)
一个容易看到的问题是,您不应该制作2个大小为inputSize/2
的数组。制作两个inputSize/2
和inputsize-inputSize/2
数组。否则算法会因奇数长度数组而失败。
也可以使用正确的参数顺序调用函数。 merge( input, left, right);
答案 1 :(得分:0)
我修复了您的代码并将它们合并为1个方法,left.length
和right.length
受input.length
限制,因此您只需要按input.length
循环:
public static void mergeSort(int[] input)
{
if (input.length < 2)
{
return;
}
int[] left = new int[input.length / 2];
int[] right = new int[input.length - input.length / 2];
for (int i = 0; i < input.length; i++)
{
if (i < input.length / 2)
left[i] = input[i];
else
right[i - input.length / 2] = input[i];
}
mergeSort(left);
mergeSort(right);
for (int i = 0, l = 0, r = 0; i < input.length; i++)
{
if (l >= left.length)
{
input[i] = right[r];
r++;
}
else if (r >= right.length)
{
input[i] = left[l];
l++;
}
else
{
if (left[l] >= right[r])
{
input[i] = right[r];
r++;
}
else
{
input[i] = left[l];
l++;
}
}
}
}
答案 2 :(得分:0)
您的代码存在两个问题:
1- as @coderredoc说:你的左右数组大小错误:
例子:如果你有一个包含7个元素的数组,你的左右数组的大小将是7/2 = 3,所以你在左右数组中总共有6个元素,而不是7个。
2-您正在使用错误的参数顺序调用mergeSort函数中的merge函数: 它应该是returnArr,left,right而不是left,right,returnArr。
说明:
如果将左数组作为第一个参数传递,它将合并右数组和左数组中的returnArr。但是你的左数组的大小为3,其他数组的大小总和为7 + 3 = 10,这就是你得到OutOfBoundsException的原因。
你需要调用merge(输入,左,右);
这是最终版本:
public class MergeSort {
public static void mergesort(int[] input) {
int inputSize = input.length;
if(inputSize < 2) {
return;
}
int[] left = new int[inputSize/2];
int[] right = new int[inputSize-inputSize/2];
int count = 0;
for(int i=0; i < inputSize/2; i++) {
left[i] = input[i];
}
for(int i=inputSize/2; i<inputSize; i++) {
right[count] = input[i];
count++;
}
mergesort(left);
mergesort(right);
merge(input,left, right);
}
public static int[] merge(int[] returnArr, int[] left, int[] right) {
int leftSize = left.length;
int rightSize = right.length;
int i = 0;
int j =0;
int k = 0;
int count = 0;
while(i < leftSize && j < rightSize) {
if(left[i] <= right[j]) {
returnArr[k] = left[i];
i++;
}
else {
returnArr[k] = right[j];
j++;
}
k++;
}
while(i<leftSize) {
returnArr[k] = left[i];
i++;
k++;
}
while(j < rightSize) {
returnArr[k] = right[j];
j++;
k++;
}
for(int x=0; x<returnArr.length; x++) {
System.out.print(returnArr[x]);
}
return returnArr;
}
public static void main(String[] args) {
int[] array = {3,4,6,2,7,1,8,6};
mergesort(array);
}
}