排序算法之归并排序

归并排序是分治思想体现得最充分的一种排序算法,所谓分治就是把多个问题拆分成若干个更容易解决的小问题

那分治是怎么应用到排序中的呢?

我们以归并排序为例把


如果我们要对它排序,那是不是可以吧它分成两个序列,分别对这两个序列进行排序之后,再将两个有序的序列按找大小合并起来呢?答案是肯定的

归并排序的最基本的思想实际上就是不停地划分序列,直至得到的子序列只有1个,然后将这些子序列按照顺序合并起来,最后得到的新的序列就是有序的,如果你没有看懂,那么下面这张流程图应该会给你一些启发

假设给定乱序的序列:10 3 5 7 100 1 2 9 6 14 12 17 21 25 27

我们首先要做的就是划分序列,一般取中间下标的元素为划分点,当我们划分得到的子序列只有1个元素时,实际上它就是有序的了,这个时候就很容易跟它的相邻子序列进行有序合并,直到将所有序列都合并成功,这样得到的新序列就是有序的了

实际上归并排序的主要流程就是2个:1.划分原序列 2.合并有序序列

假设给定的序列规模为N,那么划分流程的时间复杂度就是O(logN),合并过程的时间复杂度为O(N),所以,整个归并排序的时间复杂度就为O(N*logN),这个复杂度已经是比较排序算法中的下界了,就意味着归并排序是比较排序算法中平均性能最优的算法之一,另外,归并排序是一种稳定的排序算法,因为 大小相同的两个元素在排序前和排序后,他的相对位置是不会改变的

下面贴一下归并排序的C++代码

#include<iostream>
using namespace std;

int data[15] = {10, 3, 5, 7, 100, 1, 2, 9, 6, 14, 12, 17, 21, 25, 27};

void print(int *data, int length){
	for(int i = 0; i < length; i++){
		if(i == length - 1)
			cout << data[i] << endl;
		else
			cout << data[i] << " ";
	}
}

void merge(int *data, int begin, int pos, int end){
	int length = end - begin + 1;
	int *temp = new int[length];
	int k = 0, i = begin, j = pos + 1;
	for(; i <= pos && j <= end;){
		if(data[i] <= data[j])
			temp[k++] = data[i++];
		else
			temp[k++] = data[j++];
	}
	while(i <= pos){
		temp[k++] = data[i++];
	}
	while(j <= end){
		temp[k++] = data[j++];
	}
	//更新data
	for(int i = begin, kk = 0; i <= end && kk < k; i++, kk++){
		data[i] = temp[kk];
	}
	//回收内存
	delete temp;
}

void MergeSort(int *data, int begin, int end){
	if(begin < end){
		int pos = (begin + end) / 2;
		MergeSort(data, begin, pos);
		MergeSort(data, pos + 1, end);
		merge(data, begin, pos, end);
		print(data, 15);
	}
	
}
int main(){
	MergeSort(data, 0, 14);
	return 0;
}

结果:


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值