自下而上与自上而下的归并排序

209 阅读2分钟

自下而上与自上而下的归并排序

问题来源:我一开始也没有注意到这一点,直到我做了这个题

这个题目中所描述的归并排序是这样的:在这里插入图片描述
也就是说,对于十个元素的情况,比如
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 ;
}