随机主元快速排序

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

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

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

4比3大,不动,P2右移
在这里插入图片描述
2比三小,将2和P1所指元素互换,P1和P2都右移
在这里插入图片描述
5比3大,仅P2右移
在这里插入图片描述
同上
在这里插入图片描述
0比3小,将0和P1指向的互换,P1和P2同时右移
在这里插入图片描述
P2到达末尾,将P1指向的元素与末尾元素互换,并返回P1作为找到的主元
在这里插入图片描述
下一步对左边和右边做同样的操作,最终得到结果

#include<iostream>
#include<time.h>
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)

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值