随机主元快速排序

快速排序,也是用的分而治之的算法,但是与归并不一样的,归并排序侧重的是最后怎么把子问题合并,分解子问题就是从中间分开。快排侧重于把子问题分开的部分,而不侧重合并

下面看个将数组从小到大排序的例子:

(1)两个索引,P1和P2。
P1的左边(包括P1)是比主元小的元素,,又边则是比主元大的元素。
P2遍历没有考察的元素
随机主元快速排序_第1张图片
(2)随机选取主元。
在数组中,随机选取一个元素,令其作为标准,结束后其左边是比它小的元素,右边是比他大的元素。选取主元后,将主元放到数组最右边,方便考察。
随机主元快速排序_第2张图片
(3)开始考察

4比3大,不动,P2右移
随机主元快速排序_第3张图片
2比三小,将2和P1所指元素互换,P1和P2都右移
随机主元快速排序_第4张图片
5比3大,仅P2右移
随机主元快速排序_第5张图片
同上
随机主元快速排序_第6张图片
0比3小,将0和P1指向的互换,P1和P2同时右移
随机主元快速排序_第7张图片
P2到达末尾,将P1指向的元素与末尾元素互换,并返回P1作为找到的主元
随机主元快速排序_第8张图片
下一步对左边和右边做同样的操作,最终得到结果

#include
#include
using namespace std;

// 随机选取主元并且把数组按照主元分解,并返回主元最后的位置
int Randomized_Partition(int A[], int l,int r)
{
	int p = 0;                          // 交换媒介
	int P1 = l;
	int P2 = l;                         // 两个遍历下标 
	srand((time(NULL)));
	int s = rand() % (r - l )+ 1 + l;   // 随机选取主元

	// 交换主元到末尾
	p = A[s];
	A[s] = A[r];
	A[r] = p;

	// 遍历分解原数组
	while (P2 <r)
	{
		// P2遍历到比主元小的,就把这个元素放到左边
		if (A[P2] <= A[r])
		{
		
			
			{
				p = A[P1];
				A[P1] = A[P2];
				A[P2++] = p;
				++P1;
			}
		
		}
		// 如果没有,就直接把P2往下;
		else
		++P2;
	}

	// 把主元放中间
		p = A[r];
		A[r] = A[P1];
		A[P1] = p;

	// 返回主元现在的位置
	return P1;

}

// 主递归函数
void Randomized_QuickSort(int A[], int l,int r)
{
	// 递归出口
	if (l >= r)
		return;

	int q = 0;     // 主元所在位置
	q = Randomized_Partition(A, l, r);
	Randomized_QuickSort(A, l, q - 1);    // 处理主元左边
	Randomized_QuickSort(A, q, r);        // 处理主元右边
}


int main()
{
	int A[6] = { 3,2,5,6,0,4 };
	cout << "原数组为:";
	for (int i = 0; i < 6; ++i)
		cout << A[i] << " ";
	
	Randomized_QuickSort(A, 0, 5);
	
	cout << endl<<"快速排序后得数组为:";
	for (int i = 0; i < 6; ++i)
		cout << A[i]<<" ";
	cout << endl;
	return 0;
}

期望时间复杂度(nlogn)

你可能感兴趣的:(算法,算法,快速排序)