归并排序

归并排序(Merge Sort)

相关概念

  • 任何情况下归并排序都是稳定的,并且时间复杂度为O(NlogN)
  • 递归实现的思想采用分而治之的思想
  • 归并排序一般用于外排序
  • 小知识:在内存中进行的排序称为内部排序,而在许多实际应用中,经常需要对大文件进行排序,因为文件中的记录很多,信息量庞大,无法将整个文件拷贝进内存进行排序。因此,需要将带排序的记录存储在外存上,排序时再把数据一部分一部分的调入内存进行排序,在排序中需要多次进行内外存的交互,对外存文件中的记录进行排序后的结果仍然被放到原有文件中。这种排序方法就称外部排序。

实现描述  

  •  递归方法

 首先实现有序子列的归并

template<typename T>
void Merge(vector<T>& vec, vector<T>& tmp, int left, int right, int rightEnd) {
	int leftEnd = right - 1, pos = left, numTotal = rightEnd - left + 1;
	while (left <= leftEnd && right <= rightEnd) {
		if (vec[left] > vec[right])
			tmp[pos++] = vec[right++];
		else
			tmp[pos++] = vec[left++];
	}
	while (left <= leftEnd)
		tmp[pos++] = vec[left++];
	while (right <= rightEnd)
		tmp[pos++] = vec[right++];
	for (int i = 0; i < numTotal; i++, rightEnd--) {
		vec[rightEnd] = tmp[rightEnd];
	}
}

接着采用分而治之的方式实现递归

template<typename T>
void MSort(vector<T>& vec, vector<T>& tmp, int left, int rightEnd) {
	int center;
	if (left < rightEnd) {
		center = (left + rightEnd) >> 1;
		MSort(vec, tmp, left, center);
		MSort(vec, tmp, center + 1, rightEnd);
		Merge(vec, tmp, left, center + 1, rightEnd);
	}
}

template<typename T> // 接口
void MergeSort(vector<T>& vec) {
	const int N = vec.size();
	vector<T> tmp(N, 0);
	MSort<T>(vec, tmp, 0, N - 1);
}
  • 非递归方式

 这里将Merge最后的赋值操作注释,因为在上层会进行交换

template<typename T>
void Merge(vector<T>& vec, vector<T>& tmp, int left, int right, int rightEnd) {
	int leftEnd = right - 1, pos = left, numTotal = rightEnd - left + 1;
	while (left <= leftEnd && right <= rightEnd) {
		if (vec[left] > vec[right])
			tmp[pos++] = vec[right++]; 
		else
			tmp[pos++] = vec[left++];
	}
	while (left <= leftEnd)
		tmp[pos++] = vec[left++];
	while (right <= rightEnd)
		tmp[pos++] = vec[right++];
	//for (int i = 0; i < numTotal; i++, rightEnd--) {
	//	vec[rightEnd] = tmp[rightEnd];
	//}
}

template<typename T>
void MergePass(vector<T>& vec, vector<T>& tmp, int length) {
	const int N = vec.size();
	for (int i = 0; i < N - 2 * length; i += 2 * length) {
		Merge(vec, tmp, i, i + length, i + 2 * length - 1);
	}
	if (i + length < N)
		Merge(vec, tmp, i, i + length, N - 1);
	else
		for (int j = i; j < N; j++) tmp[j] = vec[j];
}

template<typename T> 
void MergeSort(vector<T>& vec) {
	const int N = vec.size();
	int length = 1;
	vector<T> tmp(vec.size(), 0);
	while (length < N) {
		MergePass(vec, tmp, length);
		length *= 2;
		MergePass(tmp, vec, length);
		length *= 2;
	}
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值