繁体   English   中英

为什么此MergeSort不起作用?

[英]Why is this MergeSort not working?

创建此测试代码时,我使用了Wikipedia的自顶向下的伪代码:

public static void main(String args[]) {
    int[] nums = new int[] { 17, 5, 3, 7, 6, 3, 11, 2 };
    mergeSort(nums);
    for (int i = 0; i < nums.length; i++) {
        System.out.print(nums[i] + " ,");
    }
}

public static void mergeSort(int[] A) {
    int[] B = new int[A.length];
    System.arraycopy(A, 0, B, 0, A.length);
    splitMerge(B, 0, A.length, A); // sort data from B[] into A[]
}

public static void splitMerge(int[] B, int begin, int end, int[] A) {
    if (end - begin < 2)
        return;
    int middle = (end + begin) / 2;
    splitMerge(B, begin, middle, A);
    splitMerge(B, middle, end, A);
    System.out.println("begin: " + begin +  " mid: " + ((end - begin)/2) + " end: " + end + " SIZE: " + (end-begin));
    merge(B, begin, middle, end, A);

}

public static void merge(int[] B, int begin, int middle, int end, int[] A) {
    int i = begin;
    int j = middle;
    for (int k = begin; k < end; k++) {
        if (i < middle && (j >= end || B[i] <= B[j])) {
            A[k] = B[i];
            i = i + 1;
        } else {
            A[k] = B[j];
            j = j + 1;
        }
    }
}

这应该与伪代码大致相同,那么为什么它不起作用? 这是输出:

begin: 0 mid: 1 end: 2 SIZE: 2
begin: 2 mid: 1 end: 4 SIZE: 2
begin: 0 mid: 2 end: 4 SIZE: 4
begin: 4 mid: 1 end: 6 SIZE: 2
begin: 6 mid: 1 end: 8 SIZE: 2
begin: 4 mid: 2 end: 8 SIZE: 4
begin: 0 mid: 4 end: 8 SIZE: 8
6 ,3 ,11 ,2 ,17 ,5 ,3 ,7 ,

您的B数组包含原始数组的副本,在更改原始A数组时,您永远不会更改它。

这意味着merge方法无法工作,因为它合并了两个未排序的数组(两个B子数组,在整个算法中仍保持未排序)。

为了正确进行merge ,应在合并方法begin将索引从beginend的元素从A数组复制到B数组。

您要做的就是添加语句

System.arraycopy(A, begin, B, begin, end - begin);

作为merge方法的第一条语句。

即:

public static void merge(int[] B, int begin, int middle, int end, int[] A) {
    System.arraycopy(A, begin, B, begin, end - begin);
    int i = begin;
    int j = middle;
    for (int k = begin; k < end; k++) {
        if (i < middle && (j >= end || B[i] <= B[j])) {
            A[k] = B[i];
            i = i + 1;
        } else {
            A[k] = B[j];
            j = j + 1;
        }
    }
}

这将产生输出

2 ,3 ,3 ,5 ,6 ,7 ,11 ,17 ,

给定的输入。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM