Java 合并算法
以下是merge for mergesort在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
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]