排序算法(二)-- 归并排序

归并排序

归并排序算法使用分治策略

1. 分治法

将原问题划分成n个规模较小而结构与原问题相似的子问题;递归的解决这些子问题,然后再合并其结果,就得到原问题的解。

分治模式在每一层递归上有三个步骤:
  • 分解: 将原来问题分解为一系列子问题
  • 解决: 递归地解各子问题。若子问题足够小,则直接求解
  • 合并: 将子问题合并成原问题的解。 
归并排序算法完全依照了上述模式,直观的操作如下:
  • 分解: 将n个元素分成各含n/2个元素的子序列
  • 解决: 用合并排序算法对两个子序列递归的排序
  • 合并: 合并两个已排序的子序列以得到排序结果。
在对子序列排序时,其长度为一时递归结束。单个元素被认为是排好序的。

合并排序的关键步骤在于合并两个已排序的子序列,引入作为合并的辅助过程 Merge(A,p,q,r), 其中A为数组,p,q,r是下标,满足 p<=q<r, 该过程假设子数组A[p...q]和A[q+1...r]是已经排好序的, 将它们合并成一个已经排好序的子数组代替当前子数组A[p...r].

Merge过程的时间代价为O(n),n=r-p+1是待合并元素的个数。

算法的基本步骤如图:




算法实现的伪代码如图:


通过MergeSort对其排序


其算法实现:


void Merge(int A[], int p, int q, int r)
{
	int n1 = q-p+1;		// 计算子数组A[p .. q]的长度
	int n2 = r-q;		// 计算字数组A[q+1 .. r]的长度

	int* L = new int[n1+1];     // 创建数组L(left)长度为(n1+1)
	int* R = new int[n2+1];		// 创建数组R(right)长度为(n2+1)

	// 将子数组A[p .. q]复制到L[1 .. n1]中去
	for(int i = 0; i < n1; i++)
	{
		L[i] = A[p+i];
	}
	// 将子数组A[q+1 .. r]复制到 R[1 .. n2]中去
	for(int j=0; j < n2; j++)
	{
		R[j] = A[q+j+1];
	}

	//将哨兵置于L和R的末尾
	L[n1] = 1000;
	R[n2] = 1000;

	// 这里要注意,与原书不同,C++的程序数组从[0]开始
	int i = 0;
	int j = 0;

	/* for循环每一轮迭代开始,子数组A[p .. k-1]包含了L[1..n1+1]和
	R[1 .. n2+1]中的k-p个最小的元素。并且是排好序的。此外, L[i]和R[j]
	是各自所在的数组中未被复制回数组A中的最小元素
	*/
	for(int k = p; k <= r; k++)
	{
		if(L[i] <= R[j])
		{
			A[k] = L[i];
			i++;
		}
		else
		{
			A[k] = R[j];
			j++;
		}
	}
}

// 对子数组A[p .. r]排序
/* 注: 排序中数组表示以C++为标准
	调用函数:MergeSort(A ,0,n-1);
*/
void MergeSort(int A[], int p, int r)
{
	/*
	如果p>=r ,则该子数组中至多只有一个元素。则是已经排好序的
	否则,分解步骤计算出一个下标q,将A[p .. r]分成A[p .. q]和
	A[q+1 .. r].
	*/
	int q;
	if(p <r)
	{
		q = (p+r)/2;
		MergeSort(A,p,q);
		MergeSort(A,q+1,r);
		Merge(A,p,q,r);
	}
}

(晕死,代码片不能保存,说含有敏感词汇,这里面那个词比较敏感啊?)

排序结果:



下图给出了n为2的幂时,自底向上的操作。


可以看出,递归排序比插入排序浪费空间。因为要申请一个和排序数组大小相同的数组空间,但是归并排序在性能上是优于插入排序的,它的时间复杂度远低于插入排序。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值