问题描述
因为引理中提到,
对于n位数,单位数的最大值为k,若稳定排序需要Θ(k+n)时间,则Radix sort需要Θ(d(k+n))时间。
因此一开始想用Counting sort来进行一位的排序。
代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| Array stableSort(Array A, int n, int d){ int k = 10; Array B = (ElemType*)malloc(k * sizeof(ElemType)); Array C = (ElemType*)malloc(n * sizeof(ElemType)); Array D = getSubArray(A, n, d); for(int i = 0; i < k; i++){ B[i] = 0; } for(i = 0; i < n; i++){ B[D[i]]++; } for(i = 1; i < k; i++){ B[i] += B[i - 1]; } for(i = 0; i < n; i++){ B[D[i]]--; C[B[D[i]]] = A[i]; } return A; }
|
1 2 3 4 5 6
| Array RADIX_SORT(Array A, int n, int d){ for(int i = 1; i <= d; i++){ A = stableSort(A, n, i); } return A; }
|
测试数据始终不对。后来意识到Counting sort中相同取值的数的输出顺序与输入顺序无关,因此不适用于Radix sort。
第二次还是没想放弃效率较高的算法,采用了Quicksort。
代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13
| int PARTITION(Array &A, Array &D, int p, int r){ int j = p; for(int i = p; i < r; i++){ if(D[i] < D[r]){ exchange(A, i, j); exchange(D, i, j); j++; } } exchange(A, j, r); exchange(D, j, r); return j; }
|
1 2 3 4 5 6
| void QUICKSORT(Array &A, Array &D, int p, int r){ if(p >= r) return; int q = PARTITION(A, D, p, r); QUICKSORT(A, D, p, q - 1); QUICKSORT(A, D, q + 1, r); }
|
1 2 3 4 5 6 7
| Array RADIX_SORT(Array A, int n, int d){ for(int i = 1; i <= d; i++){ Array D = getSubArray(A, n, i); QUICKSORT(A, D, 0, n - 1); } return A; }
|
发现测试数据仍不对。又意识到Quicksort其实也没有让相同取值的数的输出顺序与输入顺序相同。
为了尽快完成任务,最后采用了效率低但是输出正确的冒泡排序。
1 2 3 4 5 6 7 8 9 10
| void stableSort(Array &A, Array D, int n){ for(int i = 0; i < n - 1; i++){ for(int j = i; j < n - 1; j++){ if(D[j] > D[j + 1]){ exchange(A, j, j + 1); exchange(D, j, j + 1); } } } }
|
1 2 3 4 5 6 7
| Array RADIX_SORT(Array A, int n, int d){ for(int i = 1; i <= d; i++){ Array D = getSubArray(A, n, i); stableSort(A, D, n); } return A; }
|
分析
- 对各个排序算法的适用性不太熟悉。
- 对各个算法的书写也没完全掌握,在写不同算法时,仍会有很多小bug。
总结
因为对算法的不熟悉,导致耗费了大量时间在这一个简单的算法上。但从另一个角度说,也算是加深了对算法的理解,并且对vc++的调试更熟悉了。