Java 合并算法

Java 合并算法,java,mergesort,Java,Mergesort,以下是merge for mergesort在Java中的一个实现: void merge(int[] numbers, int low, int mid, int high) { int helper[] = new int[numbers.length]; for (int i = low; i <= high; i++) { helper[i] = numbers[i]; } int lowone = low; int lo

以下是merge for mergesort在Java中的一个实现:

void merge(int[] numbers, int low, int mid, int high) {
    int helper[] = new int[numbers.length];
    for (int i = low; i <= high; i++) {
         helper[i] = numbers[i];
    }

    int lowone = low;
    int lowtwo = mid + 1;
    int count = low;

    while (lowone <= mid || lowtwo <= high) {
        if (lowone <= mid && lowtwo <= high) {
            if (helper[lowone] <= helper[lowtwo]) {
                numbers[count] = helper[lowone];
                lowone++;
            } else {
                numbers[count] = helper[lowtwo];
                lowtwo++;
            }
        }
        else if (lowone <= mid) {
              numbers[count] = helper[lowone];
              lowone++;
            }
        else {
              numbers[count] = helper[lowtwo];
              lowtwo++;

        }
       count++;
    }
}
//msort algorithm in case it's relevant
void msort(int[] arr, int low, int high) {
    if (low < high) {
        int mid = (low + high)/2;

        msort(arr, low, mid);
        msort(arr, mid + 1, high);

        merge(arr, low, mid, high);
    }
}
void合并(int[]数字,int低,int中,int高){
int-helper[]=新的int[numbers.length];

对于(int i=low;i问题的出现是因为您在merge中更改了mid的含义。查看它的最简单方法是一个示例。假设我们有一个带索引的数组:

[0 1 2 3 4]
调用msort时,将传入0表示低,传入4表示高。这意味着mid的计算结果为2。因此,现在将数组按此方式划分(不在内存中,仅在逻辑上):

现在,当调用merge时,它被传递到mid的2中,mid是数组1中的最后一个索引。但是,在您修改的代码中,您将mid作为数组2的起始索引。这使两个数组看起来像:

[0 1] [2 3 4]
这与处理它的方式不同。一个例子是,如果你是两个数组(排序后)的样子(数字现在是值,而不是索引):

但是,在mid的解释下,数组是:

[8 12] [14 7 11]

它们不再排序。因此,您的合并功能将不起作用。

这是因为您在与第二个子数组(在
merge(…)
中)的中点进行合并之前,已将两个子列表与第一个子数组(在
msort(…)
中)的中点进行了排序

举个最简单的例子

[2,1]

像这样拆分(因为mid==((0+1)/2)==0)

[2] 及[1]

msort琐碎地将其归类为

[2] 及[1]

但是,将mid放在合并中的第二个列表中,实际上就是在合并:

[]和[2,1]

这显然会导致[2,1],这是错误的

中点位置必须在两个子阵列的拆分和合并中保持一致

[0 1] [2 3 4]
[8 12 14] [7 11]
[8 12] [14 7 11]