自顶向下的归并排序(Merge Sort) O(nlogn)

本文详细介绍了归并排序的基本思想及其实现过程,并通过图例解释了如何将数组逐步拆分和归并,最后给出了C++代码实现。

归并排序的基本思想:

          该算法是采用分治法来实现的,将原来的数组不断对半分,直到分得每个数组含有一个元素后,再一层一层归并的过程(按要求排列好)

 

下面就是将数组逐渐二分的过程:

对Level 3到Level2  的归并:

最后一层的归并:

        在上图中,将黑色箭头所指“1”与绿色箭头所指“2”进行大小比较,较小的赋值给箭头所指的“1”处。执行完这一步之后,红色箭头后移一个(到上图中的“2”),而将黑色箭头后移(指向途中的“2”,绿色箭头不动)当红色箭头指向元素组中第四个时(此时绿色箭头应该指向“8”,黑色箭头指向“3”)此时绿色箭头所指“3”小于黑色箭头所指“8”所以红色箭头所指的第四个元素应该被绿色箭头所指的“3”赋值掉,然后红色箭头后移一个(指向原数组第五个“3”)绿色箭头后移一个(指向“4”)而黑色的不动。一直进行这样的操作,直到元素组排好序。

 

自顶向下的归并排序中 归并结果的轨迹如下图:

 

 

C++代码实现:

 

 

// 将arr[left...mid]和arr[mid+1...right]两部分进行归并
void __merge(int arr[], int left, int mid, int right) {
	int *temp = new int[right - left + 1];

	for (int i = left; i <= right; i++)
		temp[i - left] = arr[i];
	
	int i = left, j = mid + 1;
	for (int k = left; k <= right; k++)
	{
		if (i > mid)//左半部分的元素全部处理完
			arr[k] = temp[j++ - left];


		else if (j > right)//右半部分的元素全部处理完
			arr[k] = temp[i++ - left];

		//两边都没处理完,比较那边的元素更小
		else if (temp[i - left] < temp[j - left])
			arr[k] = temp[i++ - left];
		else
			arr[k] = temp[j++ - left];
	}
	delete[] temp;
}
//对arr[left.....right]的范围进行排序
void __mergeSort(int arr[], int left, int right) {

	if (left >= right)	
		return;
	int mid = (left + right) / 2;

	__mergeSort(arr, left, mid);
	__mergeSort(arr, mid + 1, right);
	if (arr[mid] > arr[mid+1])
		__merge(arr, left, mid, right);
}
//归并排序要调用的函数
void mergeSort(int arr[], int n) {

	__mergeSort(arr, 0, n - 1);
}

 

 

 

 

 

 

 

自顶向下的二路归并排序算法运用分治思想来解决排序问题。原理是假设初始序列有N个元素,可将其视为N个有序的子序列,每个子序列长度为1。之后通过递归的方式不断地将序列一分为二,直至子序列长度为1,接着将这些子序列两两归并,得到长度更长的有序子序列,不断重复归并过程,直到最终得到一个长度为N的有序序列,这就是“二路归并排序”,每次归并操作都是把两个有序的子文件合并成一个有序的子文件 [^2][^3]。 以下是自顶向下的二路归并排序算法的Python实现示例: ```python def merge_sort(arr): if len(arr) <= 1: return arr mid = len(arr) // 2 left = merge_sort(arr[:mid]) right = merge_sort(arr[mid:]) return merge(left, right) def merge(left, right): result = [] i = j = 0 while i < len(left) and j < len(right): if left[i] <= right[j]: result.append(left[i]) i += 1 else: result.append(right[j]) j += 1 result.extend(left[i:]) result.extend(right[j:]) return result # 测试代码 arr = [38, 27, 43, 3, 9, 82, 10] sorted_arr = merge_sort(arr) print(sorted_arr) ``` 在这个算法中,`merge_sort` 函数负责递归地将数组分成两部分,而 `merge` 函数负责将两个有序的子数组合并为一个有序的数组自顶向下的二路归并排序算法的时间复杂度为 $O(nlogn)$,在递归的归并排序算法中,空间复杂度为 $O(n + logn)$,递归深度为 $logn$,并且该算法需要一个与原待排序记录数组同样大小的辅助数组,这是该算法的一个缺点 [^4]。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值