【排序算法】七、快速排序补充:三指针+随机数法

「前言」文章内容是对快速排序算法的补充,之前的算法流程细节多难处理,这里补充三指针+随机数法(递归),这个容易理解,在时间复杂度上也更优秀

「归属专栏」排序算法

「主页链接」个人主页

「笔者」枫叶先生(fy)

快排:三指针+随机数法

原理跟之前的一致,这里就不再解释

传统的快速排序使用两个指针(一个指向当前序列的开始,另一个指向结束),并在每次迭代中根据一个选定的"基准值"来重新排列数组

然而,为了处理一些特殊情况,比如包含大量重复元素的数组,有时可以使用三指针技术来优化性能。同时,为了增加算法的随机性并减少最坏情况发生的概率(即当输入数组已排序或接近排序时),可以使用随机数法来选择基准值

随机数法选择基准值

为了避免最坏情况的发生(即当输入数组已排序或接近排序时),可以选择一个随机的元素作为基准值,而不是总是选择第一个或最后一个元素。这可以通过生成一个随机数来实现,该随机数对应于数组中的一个有效索引

三指针

  1. left指针:指向当前已经处理好的小于基准值的元素的末尾
  2. right指针:指向当前尚未处理的元素的开始,且这些元素都大于基准值
  3. i(current)指针:当前指针,用于遍历数组,找到小于或大于基准值的元素

开始时,lefti 指向数组的起始位置,right 指向数组的末尾。遍历数组时,i 会向右移动,同时更新 leftright 的位置

数组会分成三块:[l, left-1] [left, right] [right+1, r]

算法大致分三步:

  1. 取基准值,采用随机数法
  2. 数组分三块
  3. 递归排序

代码如下:(C++)

cpp 复制代码
#include <iostream>
#include <vector>
#include <ctime>
using namespace std;

// 创建随机数
int GetRandom(vector<int>& nums, int left, int right)
{
    int rNum = rand();
    return nums[left + rNum % (right - left + 1)];
}
// quick sort: 三指针+随机数法
void QuickSort(vector<int>& nums, int l, int r)
{
    if (l >= r) return;
    // 数组分三块
    int key = GetRandom(nums, l, r);
    int left = l, i = l, right = r;
    while (i <= right)
    {
        if (nums[i] < key)
        {
            swap(nums[left], nums[i]);
            ++left;
            ++i;
        }
        else if (nums[i] == key)
        {
            ++i;
        }
        else // nums[i] > key
        {
            swap(nums[i], nums[right]);
            --right;
        }
    }
    // 递归去排序
    // [l, left-1] [left, right] [right+1, r]
    QuickSort(nums, l, left - 1);
    QuickSort(nums, right + 1, r);
}

int main()
{
    srand(time(nullptr));
    vector<int> arr = { 4, 6, 1, 0, 9, 5, 7, 7, 6, 6, 2, 3, 8 };
    QuickSort(arr, 0, arr.size() - 1);
    for (auto& x : arr) cout << x << " ";
    cout << endl;

    return 0;
}

--------------------- END ----------------------

cpp 复制代码
「 作者 」 枫叶先生
「 更新 」 2024.4.9
「 声明 」 余之才疏学浅,故所撰文疏漏难免,
          或有谬误或不准确之处,敬请读者批评指正。
相关推荐
夏鹏今天学习了吗4 小时前
【LeetCode热题100(87/100)】最小路径和
算法·leetcode·职场和发展
哈哈不让取名字4 小时前
基于C++的爬虫框架
开发语言·c++·算法
Lips6116 小时前
2026.1.20力扣刷题笔记
笔记·算法·leetcode
2501_941329726 小时前
YOLOv8-LADH马匹检测识别算法详解与实现
算法·yolo·目标跟踪
洛生&6 小时前
Planets Queries II(倍增,基环内向森林)
算法
小郭团队7 小时前
1_6_五段式SVPWM (传统算法反正切+DPWM2)算法理论与 MATLAB 实现详解
嵌入式硬件·算法·matlab·dsp开发
小郭团队7 小时前
1_7_五段式SVPWM (传统算法反正切+DPWM3)算法理论与 MATLAB 实现详解
开发语言·嵌入式硬件·算法·matlab·dsp开发
鱼跃鹰飞7 小时前
Leetcode347:前K个高频元素
数据结构·算法·leetcode·面试
bybitq7 小时前
LeetCode236-二叉树的最近公共祖先(LCA)问题详解-C++
算法·深度优先
啊阿狸不会拉杆7 小时前
《数字图像处理》第 7 章 - 小波与多分辨率处理
图像处理·人工智能·算法·计算机视觉·数字图像处理