快速排序算法

  1. 快速排序基本思想
      快速排序是基于分治的思想实现的。一个有序的序列总可以分为两部分:找一个基准值把序列一分为二,左边的区间中原始值总是小于等于基准值,右边区间中元素值总数大于等于基准值。对左右两个区间采用相同的方法直到子区间的元素个数为1,则每个基准值的位置都已正确归位置。
    在这里插入图片描述
      基本实现思路:
      ①.选取一个基准值,一般选择起始位置的值。
      ②.左右两端开始遍历,右侧区间中找一个小于基准值的位置停下,左侧区间中找一个大于基准值的位置停下,然后交互两个位置的值。
      ③.重复②③直到左右指针相遇。
      ④.交换基准位置和相遇点的值,使基准值归位。
      ⑤.同样方法递归相遇位置的左右两个子区间,直到没个点都归位。
      要让右侧指针先走,以使左右指针相遇在小于基准值的点上,然后可以交换到正确的位置。
  2. 快速排序代码实现
void qickSort(int left, int right, vector<int>& nums)
{
	int i = left;//左指针初始位置
	int j = right;//右指针初始位置
	
	if (left > right) return;
	int temp = nums[left];//基准数
	while (i != j)
	{
		//右边找一个小于基准数的位置
		while (nums[j] >= temp && i < j)
		{
			j--;
		}
		//左边找一个大于基准数的位置
		while (nums[i] <= temp && i < j)
		{
			i++;
		}
		if (i < j)
			swap(nums[i],nums[j]);
	}
	//基准数归位
	swap(nums[left],nums[j]);
	//递归左右两个子区间
	qickSort(left, i - 1, nums);
	qickSort(i + 1, right, nums);
}
  1. 三路快速排序算法
      三路快速排序是把序列分为了三个区间,然后遍历当前序列,判断当前元素需要并入哪个区间即可:
    在这里插入图片描述
      区间1中元素全部<temp,用lt表示该区间最右边位置;
      区间2中元素全部等于temp,此区间不用再进入递归;
      区间3中元素全部>temp,用rt表示该区间最左侧位置;
      仅需要递归区间1和区间2
      ①.当前值小于基准值
    在这里插入图片描述
      cur<temp,则需要把元素i并入<temp的区间:交换i和lt的下个位置的值,然后lt加1使<temp的区间增1;i位置交互过来的值是遍历过的,需要把i加1。
      ②.当前值大于基准值
    在这里插入图片描述
      cur>temp,则需要把元素i并入>temp的区间:交换i和rt的前一个位置的值,然后rt减1使>temp区间增1;因为i位置交互过来的值是未遍历到的,此时i不变。
      ③.当前值等于基准值
    在这里插入图片描述
      cur=temp,则需要把元素i并入==temp区间,此时仅i加1即可。
  2. 三路快速排序代码实现
void qicksort(int left,int right,vector<int>& nums)
    {
        if( left > right ) return;
        int temp = nums[left];//基准值
        int lt= left;//小于基准值区间的最右侧位置,初始化为基准值位置
        int rt = right+1;//大于基准值区间的最左侧位置,初始化为序列最大值下个位置
        int i = left+1;//遍历起始位置,初始为基准值下个位置
        while( i < rt)
        {
            if( nums[i] > temp)
            {
                swap(nums[i],nums[rt-1]);
                rt--;
               
            }
            else if( nums[i] < temp )
            {
                swap(nums[i],nums[lt+1]);
                lt++;
                i++;
            }
            else
            {
                i++;
            }
        }
        swap(nums[left],nums[lt]);
        qicksort(left,lt-1,nums);
        qicksort(rt,right,nums);
    }
  1. 用随机数优化
#include <cstdlib>
#include <time.h> 
using namespace std;
//随机快速排序选取的随机值,为了避免在整体大致有序的情况下产生分组不平衡现象,使算法退化
 srand(time(NULL));//更新种子
 int RAND = (rand() % (right - left) + left);//产生left和right之间的随机数
 swap(nums[left], nums[RAND]);
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值