归并排序

分治模式在每层递归是都有三个步骤:

分解原问题为若干子问题,这些子问题是原问题的规模较小的实例。

解决这些子问题,递归地求解各子问题。若子问题规模足够小,则直接求解。

合并这些子问题的解成原问题的解。


归并排序算法完全遵循分治模式。

分解:分解待排序的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]。


∞是为了方便判断L和R数组是否已经全部合并,不用每次检查是否全部合并。

MERGE算法的时间复杂度为O(n),其中n=r-p+1。


MERGE(A, p, q, r)
	n1 = q - p + 1
	n2 = r - q
	let L[1..n1 + 1] and R[1..n2 + 1] be new arrays
	for i = 1 to n1
		L[i] = A[p + i - 1]
	for j = 1 to n2
		R[j] = A[q + j]
	L[n1 + 1] = ∞
	R[n2 + 1] = ∞
	i = 1
	j = 1
	for k = p to r
		if L[i] <= R[j]
			A[k] = L[i]
			i = i + 1
		else
			A[k] = R[j]
			j = j + 1


有了MERGE后,MERGE-SORT(A,p,r)写可以很容易的实现。

伪代码如下:

MERGE - SORT(A, p, r)
	if p < r
		q = (p + r) / 2
		MERGE - SORT(A, p, q)
		MERGE - SORT(A, q + 1, r)
		MERGE(A, p, q, r)




分析分治算法


T(n)=O(1)  n<=c

T(n)=2T(n/2)+D(n)+C(n)  其他


当问题规模足够小,比如小于c,则直接求解需要常量时间。

否则,将问题分为2个子问题。分解问题需要D(n),合并需要C(n)时间。


最终T(n)=O(nlgn)



C++实现如下:

void Merge(vector<int> &A, int p, int q, int r){
	int n3 = q - p + 1;
	int n4 = r - q;
	vector<int> L(A.begin() + p, A.begin() + q + 1);
	vector<int> R(A.begin() + q + 1, A.begin() + r + 1);
	int n1 = L.size();
	int n2 = R.size();
	L.push_back(0x7fffffff);
	R.push_back(0x7fffffff);
	int i, j;
	i = 0;
	j = 0;
	for (int k = p; k <= r; ++k){
		if (L[i] <= R[j]){
			A[k] = L[i];
			++i;
		}
		else
		{
			A[k] = R[j];
			++j;
		}
	}
}

void MergeSort(vector<int> &A, int p, int r){
	if (p < r){
		int q = (p + r) / 2;
		MergeSort(A, p, q);
		MergeSort(A, q + 1, r);
		Merge(A, p, q, r);
	}
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值