数据结构学习笔记——归并排序

一、排序思想

归并排序是将两个或两个以上的有序表组合成一个新的有序表,它采用的是分治法,例如将两个有序表合并成一个有序表,即二路归并排序。归并排序的具体步骤如下:将含有n个元素的序列分为由n个长度为1的有序子表,相邻的两个有序子表通过归并算法归并为一个有序子表(两两归并),重复以上步骤,最终归并成一个有序表。

例如,对于序列{34,15,13,93,65,74,20,17},对其进行归并排序,基本过程如下:

1、将初始序列分为8个只含有1个元素的子序列:
在这里插入图片描述
2、第一趟归并。两两归并,形成若干个由两个元素组成的子序列:
在这里插入图片描述
3、第二趟归并。继续两两归并,形成两个由四个元素组成的子序列:
在这里插入图片描述
4、第三趟归并。继续两两归并,即可形成一个完整的有序序列:
在这里插入图片描述
归并排序的是一个递归的过程,分别对划分后的左右子序列进行处理,Merge()函数中借助到了一个辅助数组r1,首先将划分的子序列放在该数组相邻位置,每次从该数组的两段子序列中取出元素进行比较,较小者放回原本的数组r[]中,代码如下,:

/*归并*/
void Merge(int r[],int low,int mid,int high) {
    
    
	int *r1=(int *)malloc((high-low+1)*sizeof(int));	//辅助数组r1 
	for(int k=low; k<=high; k++)
		r1[k]=r[k];	//将r中的所有元素复制到r1中 
	for(i=low,j=mid+1,k=i; i<mid&&j<=high; k++) {
    
    //low指向为第一个有序表的第一个元素,j指向第二个有序表的第一个元素
		if(r1[i]<=r1[j])	//比较r1的左右两段中的元素 
			r[k]=r1[i++];	//将较小值复制到r1中 
		else
			r[k]=r[j++];
	}
	while(i<=mid)
		r[k++]=r1[i++];	//若第一个表没有归并完的部分复制到尾部 
	while(i<=high)
		r[k++]=r1[j++];	//若第二个表没有归并完的部分复制到尾部 
}

/*归并排序*/
void MergeSort(int r[],int low,int high) {
    
    
	if(low<high) {
    
    
		int mid=(low+high)/2;	//划分 
		MergeSort(r,low,mid);	//对左有序子表递归 
		MergeSort(r,mid+1,high);	//对右有序子表递归 
		Merge(r,low,mid,high);	//归并
	}
}

二、算法分析

分析
(1)归并排序过程中,比较次数与初始序列无关;
(2)二路归并排序中,每选出一个较小的元素需对比元素1次,可推出:在n路归并排序中,每选出一个较小的元素需对比元素的次数为m-1次;
(3)二路归并排序过程,类似于一棵倒立的二叉树,其性质符合二叉树的性质;
(4)空间复杂度:该算法中用到了递归工作栈,递归工作栈的空间复杂度为O(log2n),另外还需用到辅助数组,其空间复杂度为O(n),所以该排序算法的空间复杂度为O(n);
(5)时间复杂度:每趟归并排序的时间复杂度为O(n),整个归并排序共有⌈log2n⌉趟,所以该排序算法的时间复杂度为O(nlog2n);
(6)稳定性:归并排序是一种稳定的排序算法。
(7)适用性:归并排序可适用于顺序存储和链式存储的线性表;
(8)排序方式:归并排序是一种常用的外部排序(Out-place)。

三、总结

排序算法 空间复杂度 平均时间复杂度 最好时间复杂度 最坏时间复杂度 排序方式 稳定性 适用性
直接插入排序 O(1) O(n2) O(n) O(n2) 内部排序(In-place) 顺序存储和链式存储
折半插入排序 O(1) O(n2) O(nlog2n) O(n2) 内部排序(In-place) 顺序存储
希尔排序 O(1) 依赖于增量序列 依赖于增量序列 依赖于增量序列 内部排序(In-place) × 顺序存储
冒泡排序 O(1) O(n2) O(n) O(n2) 内部排序(In-place) 顺序存储和链式存储
简单选择排序 O(1) O(n2) O(n2) O(n2) 内部排序(In-place) × 顺序存储和链式存储
快速排序 最好为O(log2n);最坏为O(n);平均情况下,为O(log2n) O(nlog2n) O(nlog2n) O(n2) 内部排序(In-place) × 顺序存储
堆排序 O(1) O(nlog2n) O(nlog2n) O(nlog2n) 内部排序(In-place) × 顺序存储
归并排序 O(n) O(nlog2n) O(nlog2n) O(nlog2n) 外部排序(Out-place) 顺序存储和链式存储

猜你喜欢

转载自blog.csdn.net/qq_43085848/article/details/127823090
今日推荐