动画解读分治法:归并排序,快速排序

快速排序

分解:数组A[p,r]被划分为两个子数组A[p…q-1],A[q+1…r],使得A[p…q-1]每一个元素≤A[q],而A[q+1,r]每个元素>A[q]
解决:递归调用快速排序,对子数组A[p…q-1],A[q+1…r]进行排序
合并:数组都是原址排序,使用不需要合并操作,已经有序

void quicksort(int *Array, int l, int r)
{
	int i;
	if (l < r)
	{
		i=partion(Array, l, r); //分解
		quicksort(Array, l, i-1); //解决
		quicksort(Array, i + 1, r);
		//不需要合并
	}
}

关键在于分解之后,如何划分两个子数组,下面演示一轮
向左扫描直到找到小于基准的,交换
向右扫描直到找到大于基准的,交换

动画解读分治法:归并排序,快速排序_第1张图片

int partion(int *Array, int l, int r)
{
	int basic = Array[l]; int lp = l; int rp = r;
	//大于	
	while (lp < rp)
	{
		while (lp < rp && Array[rp] >= basic) rp--; Array[lp] = Array[rp];
		while (lp < rp && Array[lp] <= basic) lp++; Array[rp] = Array[lp];
	}
	Array[lp] = basic;
	return lp;
}

随机化优化

最好的情况
partion得到的两个子问题的规模都不大于n/2
最坏的情况
partion得到的两个子问题的规模分别是0和n-1

这就与我们我们选中作为基准地数字有密切的关系,实际工程中输入的排列并不是等概率的,使用我们引入随机化选择基准,然后把它和第一个交换,再执行上述带代码

int partion_Random(int *Array, int l, int r)
{
	i=rand()%(l-r+1)+l;
	int temp=Array[i];	
	Array[i]=Array[l];
	Array[l]=temp;
	partion(Array,l,r);
}

归并排序

分解:分解待排序的n个元素的序列成各具n/2个元素的两个子序列
解决:使用归并排序递归地排列连个子序列
合并:合并两个以排列地子序列产生已排序的答案

void MergeSort(int l, int r)
{
	int m;
	if (l < r)
	{
		m = (l + r) / 2;  //分解
		MergeSort(l, m); //解决
		MergeSort(m + 1, r);
		Merge(l, m, r); //合并
	}
}

关键在于如何两个有序序列合并步骤
动画解读分治法:归并排序,快速排序_第2张图片

void Merge(int l, int m, int r)
{
	int lp = l; int rp = m + 1;
	int *temp = new int[r - l + 1]; int tp = 0;
	while (lp <= m && rp <= r)
	{
		if (Array[lp] < Array[rp])temp[tp++] = Array[lp++];
		else temp[tp++] = Array[rp++];
	}
	while (lp <= m) temp[tp++] = Array[lp++];
	while (rp <= r) temp[tp++] = Array[rp++];
	for (int i = l; i <= r; i++)//copy
		Array[i] = temp[i - l];
	delete temp;
}

完整代码

动画解读分治法:归并排序,快速排序_第3张图片

#include 
using namespace std;
int partion(int *Array, int l, int r)
{
	int basic = Array[l]; int lp = l; int rp = r;
	//大于	
	while (lp < rp)
	{
		while (lp < rp && Array[rp] >= basic) rp--; Array[lp] = Array[rp];
		while (lp < rp && Array[lp] <= basic) lp++; Array[rp] = Array[lp];
	}
	Array[lp] = basic;
	return lp;
}
void quicksort(int *Array, int l, int r)
{
	int i;
	if (l < r)
	{
		i=partion(Array, l, r);
		quicksort(Array, l, i-1);
		quicksort(Array, i + 1, r);
	}
}


void Merge(int l, int m, int r,int *Array)
{
	int lp = l; int rp = m + 1;
	int *temp = new int[r - l + 1]; int tp = 0;
	while (lp <= m && rp <= r)
	{
		if (Array[lp] < Array[rp])temp[tp++] = Array[lp++];
		else temp[tp++] = Array[rp++];
	}
	while (lp <= m) temp[tp++] = Array[lp++];
	while (rp <= r) temp[tp++] = Array[rp++];
	for (int i = l; i <= r; i++)//copy
		Array[i] = temp[i - l];
	delete temp;
}
void MergeSort(int l, int r,int  *Array)
{
	int m;
	if (l < r)
	{
		m = (l + r) / 2;
		MergeSort(l, m,Array);
		MergeSort(m + 1, r, Array);
		Merge(l, m, r,Array);
	}
}
int main()
{
	cout << "快速排序:" << endl;
	int QArray[10] = { 1,5,3,4,6,8,7,9,10,2 };
	for (int i = 0; i < 10; i++)
	{
		cout << QArray[i] << " ";
	}
	cout << endl;
	quicksort(QArray, 0, 9);
	for (int i = 0; i < 10; i++)
	{
		cout << QArray[i] << " ";
	}
	cout << endl;
	cout << "二分排序:" << endl;
	int MArray[7] = { 1,3,9,4,5,3,2 };
	for (int i = 0; i <= 6; i++)
	{
		cout << MArray[i] << " ";
	}
	cout << endl;
	MergeSort(0, 6,MArray);
	for (int i = 0; i <= 6; i++)
	{
	cout << MArray[i]<<" ";
	}
}

你可能感兴趣的:(#,算法,#,算法策略,归并排序)