考研之数据结构032_算法排序_归并排序(Merge sort)

@[TOC](考研之数据结构032_算法排序_归并排序(Merge sort))

在这里插入图片描述

一、归并的思想(升序)

1、二路归并

  • 归并:把有两个或者多个有序的序列,合并成一个有序序列。

例如:将有序数组a,b进行合并到c数组中。

  1. 设置三个指针i,j,k分别指向abc三个数组的第一个元素。
  2. 将对比i,j指向的两个元素,将更小的元素放到C数组中,并将i/j和k加加(指向下一个元素)。
  3. 一直重复第二项,直到i/j超出数组的下标范围,表明i/j所代表的的a/b数组已经完成了合并。将另外一个未合并完的数组,将剩下的元素不再进行对比(退出循环),将剩下的全部加到总表C中。

在这里插入图片描述

2、多路归并

例如:四路归并,就是四个有序数列的数组中,从中选出最小的元素放到总数组中。由于有四个数组,所以至少对比三次。
结论:m归并:每选出一个元素需要对比关键字m-1次

3、归并排序(手算模拟)(算法思想)

== 核心操作:把数组内的两个有序序列归并为一个==

  • 在内部排序中,归并排序是使用的2路归并。
  • 给出一个初始序列,刚开始会把初始序列当中每一个单独的元素,都看作是一个个独立的排好序的部分(每个部分都是一个元素,所以肯定是有序的)。
  • 所以第一次排序会把两个相邻的两个部分(元素),进行二路归并。
  • 第二趟归并是基于第一趟归并的结果,也就是相邻的两个部分(两个元素)进行归并排序。
    在这里插入图片描述

二、归并排序的代码

1、二路归并代码

进行一步步分析:

1. 申请一个新数组B,大小是数组的个数。
将B数组,视为两部分:
前部分是low-mid 
后部分是:mid+1 - high
对前后两部分进行判断比较大小。
2. 归并函数:参数(数组,low,mid,high)
3. 将要排序的数组A复制给数组B。(在B中排序,一个个赋值给A数组。)
4. 主要内容:
一个要排序的数组,有7个元素,前四个和后三个是排好序的。那么:
i=low   指向的是第一个数组的第一个元素
mid     指向的是第一个数组的最后一个元素,整个数组的中间元素
j=mid+1 指向的是第二个数组的第一个元素
high    指向的是第二个数组的最后一个元素。
5. for(i=low,j=mid+1,k=i;i<=mid && j<=high;k++)
将数组视为两个排好序的数组,前部分和后半部分。
1.初始化:初始化头和尾
2.判断:是否超出A和B数组的范围
3.每一次循环,都会在新数组中添加元素,所以K++

6.判断
第一个数组的第i个元素<=第二个数组的第j个元素:
	  将i++元素    赋值给  数组[k]    i++先用后加一
else  将j++元素    赋值给  数组[k]

7. while(i/j<=mid/high)  A[k++]=B[i/j++]  先用后加!!
两个数组,总会有其中一个数组会先超出数组范围,由于上面判断的条件是:
当有超出范围的数组,循环会跳出。
所以:将未超出数组范围的有序序列,直接复制到要排序的数值当中。

在这里插入图片描述

二路排序的实际代码:

int *B=(int *)malloc(n* sizeof(int))
//A[low-mid] 和  A[mid+1 - high] 各自有序,将两部分归并
void Merge(int A[],int low,int mid,int high){
    
    
	int i,j,k;
	for(k=low,k<=high;k++)
		B[k]=A[k];  //从A复制到B数组
	for(i=low,j=mid+1,k=i; i<=mid+1 && j<=high;k++){
    
    
		if(B[i]<=B[j])
			A[k]=B[i++];
		else
			A[k]=B[j++]; 
	}// for
	//将剩下的元素放到数组A中。
	while(i<=mid) A[k++]=B[i++];
	while(j<=high) A[k++]=B[j++];

}
 

在这里插入图片描述

2. 归并排序代码

  1. 要对A数组进行归并排序,用Low和high来指定范围。
  2. 如果l<h在范围内,那么就将中间划分出mid。
  3. 将从中间mid拆分为左右两个部分:左:low-mid 右:mid+1 - high
  4. 将左右部分进行递归的归并排序。mergeSort函数
  5. 直到分为一个元素为一个数组(n个元素,那么就可以设想为有n个数组,实际就一个数组),进行merge函数排序。将该排序范围的数组A 复制到B数组,在B数组中进行对比,然后赋值给A数组。
  6. 在两个元素为一组,进行merge函数排序。…最后一组是:两个数组进行一次排序。

在这里插入图片描述

三、时间复杂度和空间复杂度

在这里插入图片描述

四、稳定性:可以稳定

在对两个有序的子序列,进行对比的时候,如果两边同时出现了,相等的情况,那么会优先的让靠左部分的子序列,先合并进去。所以是稳定的。

猜你喜欢

转载自blog.csdn.net/weixin_43989347/article/details/117663268
今日推荐