Java使用合并排序对数字数组进行排序

Java使用合并排序对数字数组进行排序,java,algorithm,sorting,Java,Algorithm,Sorting,我试图在Java中使用合并排序对数字数组进行排序。在本例中,数组为numBars。我制作了一个由30个数字组成的小数组,并附上了控制台的输出。我跟踪merge方法以了解为什么会出现索引问题。我相信我在某个地方偏离了1,但似乎不知道我的逻辑在哪里乱了套 public void mergeSort() { mergeSortHelper(numBars, 0); System.out.println(Arrays.toString(numBars)); }

我试图在Java中使用合并排序对数字数组进行排序。在本例中,数组为numBars。我制作了一个由30个数字组成的小数组,并附上了控制台的输出。我跟踪merge方法以了解为什么会出现索引问题。我相信我在某个地方偏离了1,但似乎不知道我的逻辑在哪里乱了套

public void mergeSort() {
        mergeSortHelper(numBars, 0);
        System.out.println(Arrays.toString(numBars));
    }

    public void mergeSortHelper(int[] theArray, int leftIndex) {

        //split the list in half
        int mid = theArray.length/2;
        if (mid < 1) {
            return;
        } else {
            System.out.println("Left Index is originally: " + leftIndex);
            int[] left = Arrays.copyOfRange(theArray, 0, mid);
            int[] right = Arrays.copyOfRange(theArray, mid, theArray.length);
            //sort the lower half
            mergeSortHelper(left, leftIndex);
            mergeSortHelper(right, leftIndex + left.length);
            //merge them together
            merge(left, right, leftIndex);
            System.out.println("Left Index is now: " + leftIndex);
            System.out.println("Right Index is now: " + (leftIndex + mid));
            System.out.println(Arrays.toString(numBars));
            left = Arrays.copyOfRange(numBars, leftIndex, leftIndex + mid);
            right = Arrays.copyOfRange(numBars, leftIndex + mid, leftIndex + mid + right.length);
        }
    }

    public void merge(int[]a, int[]b, int leftIndex) {
        int i = 0;
        int j = 0;
        int result = leftIndex;
        while (i < a.length && j < b.length) {
            //System.out.println("Comparing from A: " + a[i] + " Comparing from B: " + b[i]);
            if (a[i] < b[j]) {
                theCanvas.wait(theDelay);
                theCanvas.eraseRectangle(graphWidth + i * barWidth, graphHeight - barScale * numBars[i], barScale, barScale * numBars[i]);
                numBars[result] = a[i];
                result++;
                theCanvas.fillRectangle(graphWidth + i * barWidth, graphHeight - barScale * numBars[i], barScale, barScale * numBars[i]);
                i++;
            } else {
                theCanvas.wait(theDelay);
                theCanvas.eraseRectangle(graphWidth + j * barWidth, graphHeight - barScale * numBars[j], barScale, barScale * numBars[j]);
                numBars[result] = b[j];
                result++;
                theCanvas.fillRectangle(graphWidth + j * barWidth, graphHeight - barScale * numBars[j], barScale, barScale * numBars[j]);
                j++;

            }
            //System.out.println("First Loop, Comparing Size" + Arrays.toString(output));
        }
        while (i < a.length) {
            numBars[result] = a[i];
            result++;
            i++;
            //System.out.println("Second Loop, Finishing A array" + Arrays.toString(output));
        }

        while(j < b.length) {
            numBars[result] = b[j];
            result++;
            j++;
            //System.out.println("Third Loop, Finishing B array" + Arrays.toString(output));
        }
        //System.out.println(Arrays.toString(output));
    }
任何帮助都将不胜感激!谢谢

} else {
    System.out.println("Left Index is originally: " + leftIndex);
    int[] left = Arrays.copyOfRange(theArray, 0, mid);
    int[] right = Arrays.copyOfRange(theArray, mid, theArray.length);
    //sort the lower half
    mergeSortHelper(left, leftIndex);
    mergeSortHelper(right, leftIndex + left.length);
    //merge them together
    merge(left, right, leftIndex);
    System.out.println("Left Index is now: " + leftIndex);
    System.out.println("Right Index is now: " + (leftIndex + mid));
    System.out.println(Arrays.toString(numBars));
    left = Arrays.copyOfRange(numBars, leftIndex, leftIndex + mid);
    right = Arrays.copyOfRange(numBars, leftIndex + mid, leftIndex + mid + right.length);
}
最后,当您将值从
numbar
复制到
left
right
时,这完全是毫无意义的,因为这些值随后会立即超出范围并被垃圾收集

在调用者中,应该排序的数组保持不变。您需要将合并的值从
numbar
复制到作为参数的数组
theArray
,以便在调用者合并时合并已排序的数组

因此,将
else
块中的最后两行替换为

for(int i = 0; i < mid; ++i) {
    theArray[i] = numBars[leftIndex + i];
}
for(int i = mid; i < mid + left.length; ++i) {
    theArray[i] = numBars[leftIndex + i];
}
for(int i=0;i
将合并结果复制到调用方传递的同一对象中


但是,如果您将合并结果作为参数传递给
merge

的数组传递给
merge,则会产生更干净的代码。@madth3问题是,它不会引发异常。下面是发生的情况,在合并排序中,原始数组,numBars被递归地分成左右两个数组,然后左右两个数组被放回numBars,最后一部分是关于把它放回numBars,这是我遇到所有问题的地方。你能发布你的主要方法吗?还有,只是好奇,但是名称
numBars
背后的含义是什么?是的,正确指出了……合并子数组后,您不会将它们作为已排序的数组返回。
for(int i = 0; i < mid; ++i) {
    theArray[i] = numBars[leftIndex + i];
}
for(int i = mid; i < mid + left.length; ++i) {
    theArray[i] = numBars[leftIndex + i];
}