快速排序算法理解

1.分而治之思想

选取一个基准数(pivot),利用双指针相向遍历数组,然后将比基准数大的数放基准数右边,比基准数小的数放基准数左边;然后再对左右分割的两个数组各自选取pivot进行同样的操作,使用递归法直到只剩一个数。

2.递归三部曲

  • 终止条件
  • 参数和返回值
  • 单次递归逻辑

3.基准pivot的选取

对于pivot的选取有多种方案。下面进行分析:

方案1:选取边界点作为pivot

eg:nums=[5,2,3,1,9]

选取左边边界或者右边边界,此处假设pivot = nums[0];此时pivot已经记录了第一个数,第一个数的位置可以空出,相当于挖了一个洞,所以从数组右边找一个比pivot(第一个数)小的的数把洞补上;nums[0] = nums[j];数组变为nums=[1,2,3,1,9];此时显然右边重复了(挖了个洞),所以从数组左边找一个比pivot数大的数将其补上;这就是单层的逻辑;

结束条件:利用双指针相向遍历,双指针相遇的地方则为结束位置,而结束位置也将用来分割数组,作为下一层递归的边界;

代码实现:

#include <iostream>
#include<vector>
using namespace std;

class Solution {
public:
   void quicksort(vector<int> &arr,int l,int r)
{
    int i=l,j=r;
    int pivot = arr[l];
    if(l<r)
    {
        while(i<j)
        {
            while(i<j&&arr[j]>=pivot)
            {
                j--;
            }
            if(i<j)
            {
                arr[i] = arr[j];
                i++;
            }
           
            while(i<j&&arr[i]<pivot)
            {
                i++;
            }
            if(i<j) 
            {
                arr[j] = arr[i];
                j--;
            }
            
        }
        arr[i] = pivot;
        quicksort(arr,l,i-1);
        quicksort(arr,i+1,r);
    }
   
}

    vector<int> sortArray(vector<int>& nums) {
        
         int l=0,r=nums.size()-1;
         quicksort(nums,l,r);
         return nums;
    }
};

int main()
{
    Solution s1;
    vector<int> array={1,19,97,9,17,1,8,9};
    int left=0;
    int right = array.size()-1;
    vector<int> result;
    result =  s1.sortArray(array);
    for(int i=0;i<right;i++)
    {
        cout<<" "<<result[i];
    }
    return 0;
}

实验结果:

 方案2:选取中间点作为pivot

选取中间的点作为pivot,pivot =nums [ l+(l-r)/2];只需要利用双指针法,每次拿一个左边比较pivot的大的数与右边比pivot小的数交换位置即可;下面将用C语言解答

1.交换数组元素:

void swap(int *a, int *b) {
    int temp = *a;
    *a = *b;
    *b = temp;
}

2.单层递归函数

// 将数组划分为两部分,并返回枢轴的最终位置
int partition(int *nums, int low, int high) {
    int mid = low + (high - low) / 2;  // 选择枢轴元素的索引
    int pivot = nums[mid];  // 枢轴元素的值
    int i = low - 1;  // 左指针
    int j = high + 1;  // 右指针

    while (1) {
        // 移动左指针,直到找到大于等于枢轴的元素
        while (nums[++i] < pivot);

        // 移动右指针,直到找到小于等于枢轴的元素
        while (nums[--j] > pivot);

        if (i >= j)
            return j;  // 返回枢轴的最终位置

        // 交换左右指针所指的元素
        swap(&nums[i], &nums[j]);
    }
}

注意的点:1.左右指针起点,2.使用前置运算而不是后置,3.返回值

3.递归函数

// 快速排序算法
void quick_sort(int *nums, int low, int high) {
    if (low < high) {
        int pi = partition(nums, low, high);  // 划分数组并获取枢轴位置
        quick_sort(nums, low, pi);  // 对左半部分进行递归排序
        quick_sort(nums, pi + 1, high);  // 对右半部分进行递归排序
    }

注意的点:1.下一次边界的划分

方案3.随机选取pivot

待补充

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值