我一直有一个问题,我无法调试很长一段时间。我正在尝试通过遵循 Robert Sedgewick 在“C++ 中的算法”一书中的算法来实现没有额外的数组复制步骤的 MergeSort 算法。
算法的简短描述:
递归程序设置为对 b 进行排序,将结果留在 a 中。因此,编写递归调用以将其结果保留在 b 中,我们使用基本的合并程序将这些文件从 b 合并到 a 中。这样,所有数据移动都在合并过程中完成。
问题是我找不到任何逻辑错误,但排序没有正确完成。数据在某处被覆盖,我无法确定是什么逻辑错误导致了这种情况。当程序完成时,数据被排序,但它不再是相同的数据。
例如,输入数组:{ A, Z, W, B, G, C }
生成数组:{ A, G, W, W, Z, Z }
。
我显然可以看出它一定是某个地方的逻辑错误,但我一直在尝试调试它很长一段时间,我认为一双新的眼睛可能会看到我错过了什么,因为我真的找不到任何东西错误的。
我正在运行的完整代码:
//Here is my complete code that I run and that behaves as specified above.
#include <iostream>
#include <stdlib.h>
using namespace std;
// function to print the array
void print(char * a[],int l, int r)
{ for(int i=l;i<=r;i++) cout << (i+1) << ": " << a[i] << endl; }
static const int M = 1;
void insertion(char** a, int l, int r)
{ int i,j;
char * temp;
for(i=1;i<r+1;i++)
{ temp = a[i];
j = i;
while((j>0) && strcmp(a[j-1],temp)>0)
{ a[j] = a[j-1];
j = j - 1; }
a[j] = temp; } }
//merging a and b into c
void merge(char ** c,char ** a, int N, char ** b, int M)
{ for (int i=0, j=0, k=0; k<(N+M); k++)
{ if(i == N) {c[k] = b[j++]; continue; }
if(j == M) {c[k] = a[i++]; continue; }
c[k] = strcmp(a[i], b[j])<0 ? a[i++] : b[j++]; } }
void mergesortAux(char ** a, char ** b, int l, int r)
{ if(r-l <= M) { insertion(a, l, r); return; }
int m = (l+r)/2;
mergesortAux(b, a, l, m); //merge sort left
mergesortAux(b, a, m+1, r); //merge sort right
merge(a+l,b+l,m-l+1,b+m+1,r-m); } //merge
void mergesort(char ** a,int l, int r, int size)
{ static char ** aux = (char**)malloc(size*sizeof(char*));
for(int i = l; i<size; i++) aux[i] = a[i];
mergesortAux(a,aux,l,r); }
//free(aux); } I removed this piece of code as suggested, I realize it's unnecessary
int main(int argc, char * argv[])
{ int size = 6;
char **data = (char**)malloc(size*sizeof(char*));
data[0] = "A";
data[1] = "Z";
data[2] = "W";
data[3] = "B";
data[4] = "G";
data[5] = "C";
print(data,0,size-1);
printf("---------------------------\n");
mergesort(data,0,size-1,size);
printf("---------------------------\n");
print(data,0,size-1);
return 0;
}
输出:
1: A 2: Z 3: W 4: B 5: G 6: C --------------------------- --------------------------- 1: A 2: G 3: W 4: W 5: Z 6: Z