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

标签 java algorithm sorting

我正在尝试使用 Java 中的合并排序对数字数组进行排序。在本例中,数组是 numBars。我制作了一个包含 30 个数字的小数组,并附上了控制台的输出。我跟踪合并方法以了解为什么出现索引问题。我相信我在某个地方落后了 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));
    }

控制台输出:

Left Index is originally: 0
Left Index is originally: 0
Left Index is originally: 0
Left Index is originally: 1
Left Index is now: 1
Right Index is now: 2
[10, 50, 55, 99, 18, 9, 46, 80, 37, 35, 69, 77, 34, 53, 53]
Left Index is now: 0
Right Index is now: 1
[10, 55, 50, 99, 18, 9, 46, 80, 37, 35, 69, 77, 34, 53, 53]
Left Index is originally: 3
Left Index is originally: 3
Left Index is now: 3
Right Index is now: 4
[10, 55, 50, 18, 99, 9, 46, 80, 37, 35, 69, 77, 34, 53, 53]
Left Index is originally: 5
Left Index is now: 5
Right Index is now: 6
[10, 55, 50, 18, 99, 9, 46, 80, 37, 35, 69, 77, 34, 53, 53]
Left Index is now: 3
Right Index is now: 5
[10, 55, 50, 9, 46, 99, 18, 80, 37, 35, 69, 77, 34, 53, 53]
Left Index is now: 0
Right Index is now: 3
[10, 55, 50, 99, 18, 9, 46, 80, 37, 35, 69, 77, 34, 53, 53]
Left Index is originally: 7
Left Index is originally: 7
Left Index is originally: 7
Left Index is now: 7
Right Index is now: 8
[10, 55, 50, 99, 18, 9, 46, 37, 80, 35, 69, 77, 34, 53, 53]
Left Index is originally: 9
Left Index is now: 9
Right Index is now: 10
[10, 55, 50, 99, 18, 9, 46, 37, 80, 35, 69, 77, 34, 53, 53]
Left Index is now: 7
Right Index is now: 9
[10, 55, 50, 99, 18, 9, 46, 35, 69, 80, 37, 77, 34, 53, 53]
Left Index is originally: 11
Left Index is originally: 11
Left Index is now: 11
Right Index is now: 12
[10, 55, 50, 99, 18, 9, 46, 35, 69, 80, 37, 34, 77, 53, 53]
Left Index is originally: 13
Left Index is now: 13
Right Index is now: 14
[10, 55, 50, 99, 18, 9, 46, 35, 69, 80, 37, 34, 77, 53, 53]
Left Index is now: 11
Right Index is now: 13
[10, 55, 50, 99, 18, 9, 46, 35, 69, 80, 37, 53, 53, 77, 34]
Left Index is now: 7
Right Index is now: 11
[10, 55, 50, 99, 18, 9, 46, 77, 34, 53, 53, 80, 37, 35, 69]
Left Index is now: 0
Right Index is now: 7
[10, 55, 50, 80, 37, 35, 69, 77, 34, 53, 53, 99, 18, 9, 46]
[10, 55, 50, 80, 37, 35, 69, 77, 34, 53, 53, 99, 18, 9, 46]

任何帮助将不胜感激!谢谢!

最佳答案

} 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);
}

最后,当您将值从 numBars 复制到 leftright 时,这是完全没有意义的,因为这些会消失之后立即超出范围并将被垃圾收集。

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

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

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];
}

将合并结果复制到调用者传递的同一个对象中。

但是,如果您将应将合并结果放置在其中的数组作为 merge 的参数传递,这将导致代码更加简洁。

关于Java 使用归并排序对数字数组进行排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13811695/

相关文章:

java - 我应该使用八角树吗?

python - Sikuli:多个图标排序

c - 归并排序 C 实现

java - 使用 Scanner 类解析文本文件并通过多个循环计数模式出现次数

java - 在java中使用POI读取单元格范围?

java - 两种指针技术中的贪心算法(快跑者和慢跑者)

php - 当字符串数组包含 int 值时如何对其进行排序

java - 什么是java调用

java - AnimationTimer - 动画处理期间不允许使用 showAndWait

javascript - 获取大量元素的第 n 个排列