学习记录:双边递归快速排序

双边快排原理:(递增数列)

237943158
一次127943358
二次123543798
四次123543789
五次123345789
六次123345789

红色代表选过的基准)

以每个区间最左元素为基准,则从该区间最右开始。(必须从不同与基准数的一边开始)

当从右到左遇到一个数比基准小,则停止。

左边开始向右判断,当遇到一个数比基准大则停止。

左边停止的数与右边停止的数交换,这样就实现了小的数左边放,大的数右边放。

当左右遍历到同一点时,同时停止,基准数与该点的数交换。

此时该点将大区间分为两个小区间,重新取边界值重复以上步骤。

代码实现(可以优化得更简洁,时间复杂度与上述思路相同)

#include<iostream>
using namespace std;
void pivoit(int *p,int l,int r);
int main() {
	int a[10];//取十个数排序
	for (int i = 0; i < 10; i++) {
		cin >> a[i];//赋值
	}
	int l = 0, r = 9;//双边边界
	pivoit(&a[0], l, r);
	for (int i = 0; i < 10; i++) {
		printf("%d ", a[i]);
	}
	return 0;
}
void pivoit(int* a,int l,int r) {
	if (l>=r) {
		return;
	}//退出条件:左边界大于等于右边界
	int l2 = l, r2 = r, temp;//存放左右边界,方便确定下次排序边界
	while (1) {
		while (a[r2] >= a[l]) {
			r2--;
			if (l2 == r2) {
				temp = a[r2];
				a[r2] = a[l];
				a[l] = temp;
				break;
			}
		}
		if (l2 == r2) {
			break;
		}
		while (a[l2] <= a[l]) {
			l2++;
			if (l2 == r2) {
				temp = a[r2];
				a[r2] = a[l];
				a[l] = temp;
				break;
			}
		}
		if (l2 == r2) {
			break;
		}
		else {
			temp = a[l2];
			a[l2] = a[r2];
			a[r2] = temp;
		}
	}
	pivoit(&a[0], l, l2-1);
	pivoit(&a[0], l2+1, r);//更新边界递归
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值