【发布时间】:2015-06-10 19:08:44
【问题描述】:
我正在遵循 Cormen 的算法简介的2.3.1中建议的合并排序算法。但是,我没有得到正确的输出。我确信这里有一些愚蠢的错误,但我已经有一段时间无法弄清楚了。任何帮助将不胜感激。
例如:对于输入:5,4,3,2,1,我的输出是 3 1 2 4 5 而不是 1 2 3 4 5。
假设代码将针对非常小的数字进行测试,并且用999 替换标记值∞(在算法中)不会影响程序。
这里是代码,算法的相应步骤在cmets中。执行此操作是here。
#include <iostream>
using namespace std;
void merge(int* A, int p, int q, int r) { // MERGE(A,p,q,r)
int n1 = q-p+1; // 1. n1 = q-p+1
int n2 = r-q; // 2. n2 = r-q
int i,j,k;
int *L=new int[n1+1], *R = new int[n2+1]; // 3. let L[1...n1+1] and R[1..n2+1] be new arrays
for(i=0; i<n1; i++) // 4. for i = 1 to n1
L[i]=A[p+i]; // 5. L[i] = A[p+i-1]
//the modification in above line is deliberately done to avoid IndexOutOfBounds when p=i=0 and is not because I forgot to subtract 1
for(j=0; j<n2;j++) // 6. for j = 1 to n2
R[j]=A[q+j]; // 7. R[j] = A[q+j]
L[n1]=999; //sentinel // 8. L[n1+1]= ∞
R[n2]=999; //sentinel // 9. R[n2+1]= ∞
i=0; // 10. i = 1
j=0; // 11. j = 1
for(k=p; k<r; k++) { // 12. for k = p to r
if(L[i]<=R[j]) // 13. if(L[i]<=R[j])
A[k]=L[i++]; // 14. A[k] = L[i]
// 15. i = i+1
else // 16. else A[k] = R[j]
A[k]=R[j++]; // 17. j = j+1
}
delete(L);
delete(R);
}
void mergeSort(int* a, int p, int r) { // MERGE-SORT (A,p,r)
if(p<r) { // 1. if p<r
int q=(p+r)/2; // 2. q = (p+r)/2
mergeSort(a,p,q); // 3. MERGE-SORT(A,p,q)
mergeSort(a,q+1,r); // 4. MERGE-SORT(A,q+1,r)
merge(a,p,q,r); // 5. MERGE(A,p,q,r)
}
}
int main() {
int arr[]={5,4,3,2,1};
mergeSort(arr,0,5);
for(int i=0; i<5; i++)
cout << arr[i]<<" ";
}
【问题讨论】:
-
“但是,我没有得到正确的输出。”你得到什么输出?预期的输出是多少?请提供Minimal, Complete, Verifiable Example
-
我添加了ideone链接供大家查看。但为了完整起见,我仍然会对其进行编辑。 :)
-
另外...您不想对大于 999 的数字进行排序?
-
没有。仅适用于小数字。如果需要,我总是可以通过调用库函数将标记更改为可能的最大整数。但现在,我只想对小数字进行排序。
-
@Cheersandhth.-Alf,我只是想理解算法,所以使用了一个整数数组。我现在并没有真正实施任何大的东西。否则,与此相比,库调用非常有效。