归并排序

归并排序


归并排序的一般步骤是先划分、再排序、后合并,这也就符合了分治法的思想

image.png

对序列r[]用归并排序进行升序排列,s为开始下标,t为末尾下标,m为中间下标,伪代码如下:

1、如果s==t,则待排序区间只有一个元素,算法结束

2、计算中点:m=(s+t)/2;

3、对前半部分序列r[s]~r[m]进行升序排序,对后半部分r[m+1]~r[t]进行升序排序

4、合并两个升序序列


c++算法如下:

#include<iostream>
using namespace std;
void merge(int r[], int temp[], int s, int m, int t){ //合并子序列(按从小到大合并)
        //i是前半部分的下标,j是后半部分的下标,k则是临时数组temp的下标
	int i = s, j = m + 1, k = s;
	while (i <= m &&  j <= t){
		if (r[i] < r[j]){
			temp[k++] = r[i++]; //取值小者放入temp
		}
		else{
			temp[k++] = r[j++];
		}
	}
	while (i <= m){  //若前半部分序列未处理完,则直接加到临时数组temp中
		temp[k++] = r[i++];
	}
	while (j <= t){ //若后半部分序列未处理完,则直接加到临时数组temp中
		temp[k++] = r[j++];
	}
}
void mergeSort(int r[], int s, int t){  //对序列r[s]-r[t]进行归并排序
	int m, temp[100];  //m是划分点,temp是临时数组
	if (s == t){   //如果s==t,说明只有一个元素了,则返回(递归边界)
		return;
	}
	else{   //递归
	       //划分,即使s+t为奇数也能向上取整,不影响排序结果
		m = (s + t) / 2;  
		mergeSort(r, s, m);  //递归前半部分
		mergeSort(r, m + 1, t);//递归后半部分
		merge(r, temp, s, m, t);//合并两个有序子序列,结果保存在temp中
		for (int i = s; i <= t; i++){  //将排序后的temp传回r数组中
			r[i] = temp[i];
		}
	}
}
void main(){
	int r[8] = { 15,8, 3, 24, 6, 30, 13, 4 };
	mergeSort(r, 0, 7);  //从0开始到n-1
	for (int i = 0; i < 8; i++){
		cout << r[i] << "\t";
	}
}

运行结果:

image.png

算法的复杂度分析:

1、其中用到了临时数组temp,故空间复杂度为O(N)

2、其中的递推公式为:T(N) = 2T(N/2) + O(N),所以时间复杂度为O(N*log2N)

【注意】归并排序的比较次数是所有排序中最少的,因为它一开始只是不断的划分,真正的比较发生在合并为有序序列时

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值