快排之递归与非递归

前言

时间过得很快,今年就轮到我秋招找工作了,偶尔复习下常见的算法题并进行整理。方便自己后面复习,能给网友提供点参考也不错。

partition函数

该函数为快排的核心,思想就是在数组中找一个数作为中间值,把数组中比它小的放左边,大的放右边。这个函数有两种写法,单指针版和双指针版。下面给出C++代码:

//单指针分割 
int singlePartition(vector<int>& nums, int begin, int end){
	int randIdx = rand()%(end-begin+1)+begin;
	swap(nums[randIdx],nums[end]);
	int index = begin;
	for(int i = begin; i < end; ++ i){
		if(nums[i]<=nums[end]) {
		    swap(nums[index++],nums[i]);
		}
	}
	swap(nums[index],nums[end]);
	return index;
}

//双指针分割 
int doublePartition(vector<int>& nums, int begin, int end){
	int randIdx = rand()%(end-begin+1)+begin;
	swap(nums[begin],nums[randIdx]);
	int l = begin, r = end, x = nums[l];
	while(l<r){
		while(l<r&&nums[r]>=x) --r; 
		if(l<r&&nums[r]<x) swap(nums[r],nums[l]);
		while(l<r&&nums[l]<=x) ++l;
		if(l<r&&nums[l]>x) swap(nums[r],nums[l]);  
	}
	nums[l] = x;
	return l;
}

递归与非递归

递归版本就是对一组数据进行partition之后,对分界值的左半部分和右半部分分别进行相同操作,直到数组大小减到1停止。非递归版本其实就是用一个栈来保存左右边界下标,在栈弹空之前以栈顶两元素作为左右边界下标进行partition。思路都很简单,下面直接给出代码:

//递归版快排 
void recQsort(vector<int>& nums, int begin, int end){
	if(begin>=end) return;
	int mid = singlePartition(nums,begin,end);
	recQsort(nums,begin,mid-1);
	recQsort(nums,mid+1,end);
}

//非递归版快排
void Push(stack<int>& s, int left, int right){
	s.push(left);
	s.push(right);
} 
void norecQsort(vector<int>& nums, int begin, int end){
	stack<int> s;
	Push(s,begin,end);
	while(!s.empty()){
		int r = s.top(); s.pop();
		int l = s.top(); s.pop();
		if(l>=r) continue;
		int mid = singlePartition(nums,l,r);
		Push(s,l,mid-1);
		Push(s,mid+1,r);
	}
}
  • 8
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值