快速排序(随机化快速排序 随机主元)java代码(递归实现)分治法(分而治之)

固定主元的快速排序:

1.首先选取一个主元(一般取数组的头部或者尾部为主元);
2.把其他数与主元比较,如果比主元小,放主元左边,如果比主元大,放主元右边;(这个时候主元左边的数都只是比主元小,左边的数还没有从小到大排好,右边也是)。
3.对主元左边数组段重复1,2步骤;对右边也重复1,2步骤。

ps:上述步骤2的具体实现说明(主元以每次选取数组尾端元素为例):
1.创建两个指针i,j;i初始值为数组头部元素下标减一,j为数组头部元素下标(i左边存放比主要小的元素,i到j存放比主元大的元素,等到j走到尾端要交换主元素时,i+1元素与主元交换即可)
2.j进行移动并与主元进行判断;如果j所对应元素小于主元,j++,i不操作;如果大于,i++,i和j所指元素进行交换,j++.

固定主元的弊端:

如果需要排序的序列为234561 ,那么会使得算法的时间复杂度为:O(n2).
为了避免这种情况,选择随机的主元是一个很好的方式。

随机主元的快速排序(随机化快速排序):

也就是用系统生成随机数的方法去选择数组下标作为主元,选择后便与数组最后一个元素进行交换,之后的步骤就与固定主元的快速排序相同。
随机主元的快速排序它的时间复杂度的数学期望为:O(nlogn)。
步骤如下:
1.首先选取一个随机主元,与数组尾端元素进行交换.
2.把其他数与主元比较,如果比主元小,放主元左边,如果比主元大,放主元右边;(这个时候主元左边的数都只是比主元小,左边的数还没有从小到大排好)。
3.对主元左边数组段重复1,2步骤;对右边也重复1,2步骤。

ps:上述步骤2的具体实现参考固定主元的快速排序中的ps.

举例:
比如给定数组为945721683,下面我们对其进行分析:
开始——>(比主元大的用蓝色表示,比主元小的用橙色表示,i指向数组首端的前一个,j指向数组首端,即i=left-1,j=left).
刚开始i指向空,j指向9.
1.随机选择主元,假设选择主元为6;
2.主元6与末尾8交换,变为:945721386
3.主元6与j所指9比较,比6小,j++,j指向4,数组变为:945721386
4.主元6与j所指4比较,比4大,i++,i此时指向9,i与j交换,j++,变为:495721386
5.主元6与j所指5比较,比5大,i++,i此时指向9,i与j交换,j++,变为:459721386
6.主元6与j所指7比较,比7小,j++,变为:457921386
7…省略2138的比较与上述类似,变为:452139786
8.j指向了数组最后一个,即主元,则i+1与主元交换,即9与主元6交换
9.然后递归调用本函数,左边参数的left = left,right = i;右边参数的left = i+2,right= right;递归出口条件为left>=right.

java代码实现随机化快速排序:

public void toQuickSort(int []arr,int left,int right) {
	if(left>=right) 
		return;
	int principalElement = left+(int)(Math.random()*(right-left+1));  //选取随机主元
	//把随机主元放到数组尾部
	int temp = arr[principalElement];
	arr[principalElement] = arr[right];
	arr[right] = temp;
	//数组中元素与主元比较
	int i = left-1;
	for(int j = left;j<=right;j++) {
		if(arr[j]<arr[right]) {
			i++;
			int temp1 = arr[i];
			arr[i] = arr[j];
			arr[j] = temp1;
		}
	}
	//最后把主元放到适当位置
	int temp2 = arr[right];
	arr[right] = arr[i+1];
	arr[i+1] = temp2;
	
	toQuickSort(arr,left,i);
	toQuickSort(arr,i+2,right);
}

函数调用,运行结果:

在这里插入图片描述
在这里插入图片描述

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

MrYuShiwen

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值