自下而上与自上而下的归并排序
问题来源:我一开始也没有注意到这一点,直到我做了这个题
这个题目中所描述的归并排序是这样的:
也就是说,对于十个元素的情况,比如
3 1 2 8 7 5 9 4 6 0
相邻元素两两结合后,就成了
(3 1)(2 8)(7 5)(9 4)(6 0)
一次排序后为
(1 3)(2 8)(5 7)(4 9)(0 6)
二次排序后为
(1 2 3 8)(4 5 7 9)(0 6)
三次排序后为
(1 2 3 4 5 7 8 9)(0 6)
四次排序后为
(0 1 2 3 4 5 6 7 8 9)
以上为“自下而上”的归并排序
但是!!!
如果为“自上而下”的归并排序
(3 1 2 8 7 5 9 4 6 0)
第一次递归下去
(3 1 2 8 7)(5 9 4 6 0)
第二次递归下去
(3 1 2)(8 7)(5 9 4)(6 0)
第三次递归下去
(3 1)(2)(8 )(7)(5 9)(4)(6)(0)
第四次递归下去
(3)(1)(2)(8)(7)(5)(9)(4)(6)(0)
第一次回溯(一次排序后为)
(1 3)(2)(7 8)(5 9)(4)(0 6)
第二次回溯(二次排序后为)
(1 2 3)(7 8)(4 5 9)(0 6)
第三次回溯(三次排序后为)
(1 2 3 7 8)(0 4 5 6 9)
第四次回溯(四次排序后为)
(0 1 2 3 4 5 6 7 8 9)
我们不难发现,两次过程中的数组排列情况是不同的
因此,在归并排序方面,要认识到自上而下与自下而上的区别
---------------------------------------------------------------------------------------------------------------------
代码实现
void Merge_sort_downtoup(){
int t = 2;//最小分割单元
while(t <= n){
for(int i = 1; i <= n; i += t){
sort(a + i, a + min(i + t, n + 1));//注意sort的使用
}
/*这里可以进行一些操作 */
t *= 2;
}
return ;
}
void Merge_sort_uptodown(int l, int r){
if(l == r) return ;
int mid = (l + r) / 2;
Merge_sort_uptodown(l, mid);
Merge_sort_uptodown(mid + 1, r);
int i = l, j = mid + 1, t = l;
while(i <= mid && j <= r){
if(a[i] <= a[j]){
k[t] = a[i];
t ++;
i ++;
}
else{
k[t] = a[j];
t ++;
j ++;
}
}
while(i <= mid){
k[t] = a[i];
t ++;
i ++;
}
while(j <= r){
k[t] = a[j];
t ++;
j ++;
}
for(int i = l; i <= r; ++ i)
a[i] = k[i];
return ;
}