首页 > 编程语言 >最优雅的算法——快速排序

最优雅的算法——快速排序

时间:2024-12-20 18:57:45浏览次数:9  
标签:right int 优雅 dat 算法 low 排序 left

快速排序:探索两种流行的方法

快速排序,这个听起来有点技术性的术语,实际上是一个既高效又优雅的算法,它能够将一堆混乱的数据快速整理得井井有条。今天,我们将通过一种轻松愉快的方式,一起揭开快速排序的神秘面纱,并探索两种流行的实现方法。
话不多说,开始战斗
在这里插入图片描述

快速排序的魔法:基本原理

想象一下,你有一副乱序的扑克牌,你想要快速地将它们按照大小排列。快速排序的魔法就在于,你每次都从牌堆中挑出一张牌作为“基准牌”,然后根据这张牌将其他牌分成两堆:一堆比它小,一堆比它大。这样,每次你都能迅速地将牌堆分成更小的部分,然后重复这个过程,直到所有的牌都被有序地排列好。

方法一:三数取中法

代码解析与注释

void quick_sort(int* data, int ns) {
    // 初始化变量,end代表数组的最后一个元素的索引
    int end = ns - 1;
    // left和right分别代表当前分区的左右边界
    int left = 0;
    int right = end;
    // 选择中间元素作为基准值,这是一种常见的选择基准的方法
    int mid_val = data[end / 2];
    while (left <= right) {
        // 从左向右找,直到找到一个大于等于基准值的元素
        while (data[left] < mid_val)
            left++;
        // 从右向左找,直到找到一个小于等于基准值的元素
        while (data[right] > mid_val)
            right--;
        // 如果left小于right,说明找到了一对可以交换的元素
        if (left < right) {
            int temp = data[left];
            data[left] = data[right];
            data[right] = temp;
            // 移动指针,继续寻找下一对可以交换的元素
            left++;
            right--;
        }
        // 如果left和right相遇,说明这一轮没有找到可以交换的元素
        else if (left == right) {
            left++;
            right--;
        }
    }
    // 如果左边还有元素,递归地对左边的子数组进行快速排序
    if (left < end)
        quick_sort(data + left, end - left + 1);
    // 如果右边还有元素,递归地对右边的子数组进行快速排序
    if (right > 0)
        quick_sort(data, right + 1);
}

方法二:单基准法

代码解析与注释

int purtition(int* dat, int low, int high) {
    // 选择数组的第一个元素作为基准
    int pivot = dat[low];
    while (low < high) {
        // 从右向左找,直到找到一个小于基准值的元素
        while (low < high && dat[high] >= pivot)
            high--;
        // 将找到的元素放到左边
        dat[low] = dat[high];
        // 从左向右找,直到找到一个大于基准值的元素
        while (low < high && dat[low] <= pivot)
            low++;
        // 将找到的元素放到右边
        dat[high] = dat[low];
    }
    // 基准元素归位
    dat[low] = pivot;
    return low; // 返回基准元素的最终位置
}

void quick_s(int* dat, int low, int high) {
    int mid;
    // 如果区间无效,直接返回
    if (low >= high)
        return;
    // 进行分区操作,并获取基准元素的最终位置
    mid = purtition(dat, low, high);
    // 对基准左边的子数组递归进行快速排序
    quick_s(dat, low, mid - 1);
    // 对基准右边的子数组递归进行快速排序
    quick_s(dat, mid + 1, high);
}

void quick_sort2(int* dat, int ns) {
    // 从整个数组开始进行快速排序
    quick_s(dat, 0, ns - 1);
}

总结

快速排序就像是一个魔术师,它用巧妙的手法将混乱变得有序。三数取中法和单基准法都是这个魔术师的拿手好戏,它们各有千秋,但都能达到同样的效果——快速地将数据排序。希望这篇文章能让你对快速排序有了更生动、更清晰的理解。如果你对快速排序还有任何疑问,或者想要了解更多的算法知识,欢迎在评论区交流讨论!

标签:right,int,优雅,dat,算法,low,排序,left
From: https://blog.csdn.net/Giants2024/article/details/144537636

相关文章

  • 【字符串匹配算法——BF算法】
    ......
  • 机器学习之聚类(k均值聚类、层次聚类、密度聚类、EM算法、高斯混合模型)思维导图
    学习笔记—机器学习-聚类(k均值聚类、层次聚类、密度聚类、EM算法、高斯混合模型)思维导图20241220,以后复习看。(西瓜书+统计学习方法)学的迷糊的,如果错别字,请忽略。PS:图片看不清,可以下载下来看。往期思维导图:机器学习之集成学习Bagging(随机深林、VR-树、极端随机树)思维导......
  • Nginx 优雅重启机制
    nginx的进程模型主进程(MasterProcess):负责管理Nginx的工作进程,处理配置文件的加载和维护。工作进程(WorkerProcesses):实际处理客户端请求,每个工作进程是独立的。reload过程接收SIGHUP信号主进程接收到SIGHUP(挂起)信号,表示需要重新加载配置。解析新配置1.主进程开始读......
  • 操作系统里的算法
    处理机管理调度算法先来先服务调度算法(firstcomefirstserver,FCFS)简介;先来先服务调度算法是最简单的调度算法,系统按照作业到达的先后次序进行调度。优点:有利于长作业,适合繁忙的工作缺点:不利于短作业短作业优先调度算法(shortjobfirst,SJF)简介:按照作业的长短来计......
  • 排序算法
    1.快速排序intPartition(SqListL,intlow,inthigh){L.elem[0]=L.elem[low];intl=low,r=high;while(l<r){while(r>l&&L.elem[r]>=L.elem[0])r--;L.elem[l]=L.elem[r];while(l<r&&L.elem[l]<=L.elem[0])l++;L.elem[r]=L.elem[l];......
  • K - means 聚类算法
    一、引言在数据挖掘和机器学习领域,聚类算法是一种重要的无监督学习方法,用于将数据集中的数据点划分为不同的组或簇。K-means聚类算法是其中最为经典和广泛应用的算法之一,它简单且高效,能够快速地对大规模数据集进行处理。本文将详细介绍K-means聚类算法的原理、应用场景......
  • 【机器学习与数据挖掘实战】案例05:基于决策树、梯度提升和XGBoost分类算法的O2O优惠券
    【作者主页】FrancekChen【专栏介绍】⌈⌈⌈机器学习与数据挖掘实战案例⌋......
  • 算法网关视频分析网关:安防监控摄像机有哪些最新技术趋势?
    在当今这个信息化快速发展的时代,安防监控摄像机技术正经历着一场革命性的变化。这些变化不仅提高了监控系统的效能,也为安全管理带来了新的视角和解决方案。随着人工智能、物联网、高清视频技术等前沿科技的融合,安防监控摄像机的最新技术趋势正在重塑我们对安全监控的认知。以下是......
  • 六大排序(一):插入,冒泡,选择排序
    一.插入排序:a)步骤:1.从第一个元素起,并认为已是排好序了的2.选择下一个元素tmp,从已经排好序的元素从后往前扫描3.若大于tmp则往前移动一个,直到小于tmp,并把tmp插入这个元素前面4.若都大于tmp,则插入0的位置5.重复以上步骤,直到全部排序完毕b)例子:对13528479排序1......
  • python优雅而神奇的parse库
    前言在Python中,format方法和f-strings是两种常用的字符串插值方法。name="Haige"age="18"print(f"{name}is{age}yearsold.")#Haigeis18yearsold.而如果是要从字符串中提取期望的值呢?相信很多人的第一或第二想法是使用正则表达式。熟悉正则表达式的人都明白......