快速排序:这个让程序员又爱又恨的算法到底有多神奇?

没事儿就学习(5):快速排序(Fortran)       老师让我学Fortran以备不时之需,刚好又在复习数据结构,那就先把C++放一边去,拿Fortran来写个快速排序快速入门算了。于是感觉坑好深........被水淹没不知所措。(突然感觉C++真简单)      一上来肯定是用Fortran写一个“Hello World”以表尊敬,于是就出现了下面的代码。program Hello implicit none character(1... 阅读详情

🔥 当数组乱成一锅粥时…

各位老铁们有没有遇到过这样的情况?手头有个数组(Array)乱得跟双十一后的快递站似的,这时候领导突然要你立即(划重点)把数据整理成有序排列。这时候要是只会冒泡排序(Bubble Sort),估计得当场表演一个原地爆炸——毕竟O(n²)的时间复杂度可不是开玩笑的!

(这时候就该我们的主角登场了)👉 快速排序(Quick Sort)这个算法界的闪电侠,用O(n log n)的平均时间复杂度,分分钟教数组重新做人!不过别高兴太早,这货虽然快起来像打了鸡血,但要是用错了姿势,分分钟能给你掉链子到O(n²)的深渊里…

🧠 快速排序的"三板斧"哲学

1. 分而治之(Divide and Conquer)的精髓

这算法的核心思想就像古代打仗的兵法:“把大问题拆成小问题,逐个击破!”(此处应有掌声👏)具体操作分三步走:

  • 选个"带头大哥":在数组中随便挑个元素当基准值(Pivot),这步可讲究了!选得好就是人生赢家,选得不好就…(后面再说)

  • 左右分队大作战:把比基准值小的扔左边,大的扔右边,相等的…爱去哪去哪(其实两边都行)

  • 递归搞起来:对左右两个子数组重复上述过程,直到每个小组只剩一个元素(或者空数组)

2. 基准值的选秀大会

这里有个隐藏的陷阱(新手必踩坑警告⚠️)!选基准值就像给班级选班长:

  • 选第一个元素当Pivot?万一数组本来就是倒序的…(那酸爽!)

  • 选中间元素?看起来不错但需要额外计算

  • 随机选?这倒是个保命秘籍,不过要多写几行代码

(偷偷告诉你们)现在流行的是"三数取中法"——取首、中、尾三个元素的中位数。这样既能避免最坏情况,代码实现也不复杂,堪称性价比之王!👑

3. 分区操作的骚操作

这里给大家看个C语言的经典实现,感受下指针共舞的美学:

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

int partition(int arr[], int low, int high) {
    int pivot = arr[high];  // 选最后一个元素当基准
    int i = (low - 1);      // 小于基准的边界指针

    for (int j = low; j <= high - 1; j++) {
        if (arr[j] < pivot) {
            i++;
            swap(&arr[i], &arr[j]);
        }
    }
    swap(&arr[i + 1], &arr[high]);
    return (i + 1);
}

注意看那个i指针,就像个勤劳的交通警察,把比基准小的车都疏导到左边车道。最后那个swap操作,就是把基准值放到正确的位置上,这波操作我给满分!💯

⚡ 性能大起底:快的时候像火箭,慢的时候像蜗牛

1. 时间复杂度那些事儿

  • 最佳情况:每次都能完美平分数组 → O(n log n)

  • 平均情况:O(n log n) → 这也是它名字的由来

  • 最差情况:每次选的基准都是极值 → O(n²)(这时候连冒泡排序都不如!)

(血泪教训)当年有个哥们用快速排序处理已经排好序的数组,结果程序直接卡死…后来发现他每次都选第一个元素当基准,这酸爽!

2. 空间复杂度揭秘

虽然说是原地排序(In-place),但递归调用栈还是会占用空间:

  • 最佳情况:O(log n)

  • 最差情况:O(n)

所以对于内存吃紧的嵌入式系统,可能还是得考虑其他算法(比如堆排序)

🚀 优化方案大赏

1. 当数组变小时…

(划重点)当子数组长度小于某个阈值(比如10)时,切换到插入排序!因为对于小规模数据,插入排序的实际速度更快,还能减少递归开销。

2. 三路快排的魔法

遇到大量重复元素时,传统快排会变慢。这时候就要祭出三路快排(3-way Partitioning)的大招,把数组分成三部分:小于、等于、大于基准值的元素。

3. 尾递归优化

把第二个递归调用改成循环,能有效减少栈深度。这个技巧在C/C++这种没有自动尾调用优化的语言里特别有用!

💻 手把手实现优化版快排(C语言)

// 三数取中法选基准
int medianOfThree(int arr[], int low, int high) {
    int mid = low + (high - low) / 2;
    
    if (arr[low] > arr[mid])
        swap(&arr[low], &arr[mid]);
    if (arr[low] > arr[high])
        swap(&arr[low], &arr[high]);
    if (arr[mid] > arr[high])
        swap(&arr[mid], &arr[high]);
    
    return mid;
}

void quickSort(int arr[], int low, int high) {
    // 当子数组长度小于10时切换插入排序
    if (high - low + 1 < 10) {
        insertionSort(arr, low, high);
        return;
    }

    while (low < high) {
        int pi = partition(arr, low, high);

        // 优先处理较小的子数组
        if (pi - low < high - pi) {
            quickSort(arr, low, pi - 1);
            low = pi + 1;
        } else {
            quickSort(arr, pi + 1, high);
            high = pi - 1;
        }
    }
}

这个优化版实现了:

  1. 三数取中法选基准
  2. 小数组转插入排序
  3. 尾递归优化
  4. 迭代代替部分递归

🤔 灵魂拷问:什么时候不该用快排?

虽然快排是很多语言标准库的默认排序算法(比如C的qsort、Java的Arrays.sort),但遇到以下情况请三思:

  1. 内存极度紧张:递归调用可能爆栈

  2. 需要稳定排序(相等元素保持原顺序):快排天生不稳定

  3. 数据几乎已排序且无法优化基准选择

  4. 最坏情况无法容忍的场景(比如实时系统)

🎯 终极选择题:快速排序 vs 归并排序

这俩时间复杂度都是O(n log n),但:

  • 快速排序:平均更快,原地排序,但最差情况O(n²)

  • 归并排序:稳定排序,始终O(n log n),但需要额外O(n)空间

(个人经验)在内存充足的现代计算机上,快速排序通常是更好的选择。但如果是排序链表,归并排序就是天选之子!

🌟 彩蛋:那些你不知道的冷知识

  1. 快速排序是图灵奖得主Tony Hoare在1960年发明的,当时他还在莫斯科大学读书!

  2. Java7之后的Arrays.sort改用TimSort(归并排序+插入排序的混合体),因为实际数据经常部分有序

  3. Linux内核的qsort实现有个隐藏优化:当检测到已经基本有序时,会自动切换到插入排序

💡 最后的小建议

下次面试官让你手写快排时,记得:

  1. 先问数据规模
  2. 确认是否需要稳定排序
  3. 讨论基准选择策略
  4. 提到优化方案(比如小数组转插入排序)

(保命绝招)如果实在写不出来,可以真诚地说:“其实在实际开发中,我更倾向于使用标准库的排序函数,因为它们都经过深度优化…”(然后露出职业微笑😊)

【NOJ1003】【算法实验一】【分治算法】快速排序 1003.快速排序 时限:1000ms 内存限制:10000K  总时限:3000ms 描述 给定一个数列,用快速排序算法把它排成升序。   输入 第一行是一个整数n(n不大于10000),表示要排序的数的个数;下面一行是用空格隔开的n个整数。   输出 输出排序后的数列,每个数字占一行。   输入样例 5 3 2 1 4 5   输出样例 1 2 3 4 5 #... 阅读详情

相关推荐

RML2016.10a (CNN、LSTM、CNN-LSTM、CNN-LSTM-Multi-head-attention, TensorFlow)

RML2016.10a (CNN、LSTM、CNN-LSTM、CNN-LSTM-Multi-head-attention, TensorFlow) 包含所有数据和代码,支持一键运行(jupyter)

qq_40999533的博客 1482

编程的又爱又恨:从报错崩溃到用代码造物的成长之路

编程不仅是语法堆砌,更是将抽象逻辑转化为可执行结果的过程。从初学者用Python绘制爱心代码获得第一次成就感,到通过罗盘时钟代码理解Canvas绘图与时间计算原理,这背后体现的是递归、排序、依赖管理等核心概念如何支撑真实项目的运转。当面对乱码、时区错位、库冲突等常见工程问题时,掌握最小可运行原则与报错排查思维,能让开发者从被Bug支配的恐惧中解放出来。代码既是折磨人的对手,也是成就人的工具——理解其底层原理,善用AI辅助开发,就能在又爱又恨的日常中持续成长。本文结合个人踩坑经历,分享从崩溃到上头的编程心法。

weixin_33226548的博客 306

【OpenClaw 故障排查完全指南】

OpenClaw 故障排查指南摘要 本指南针对OpenClaw 2026.2.26版本常见问题提供解决方案,适用于Windows/Linux/macOS平台。 核心问题及修复方案: 飞书插件连接失败:删除冲突插件或重装OpenClaw Ollama认证错误:设置环境变量OLLAMA_API_KEY="ollama-local" 配置警告:可安全忽略的安全扫描提示 端口占用:查找并终止占用18789端口的进程 插件重复加载:清理重复插件目录 快速修复: 提供一键修复PowerShell脚本

weixin_37572294的博客 1万+

那些让你直呼“绝了!”的算法,到底有多神奇?

算法,是程序员手中的“魔法棒”,也是解决问题的“最优解”。有些算法看似平平无奇,却能以四两拨千斤的巧思惊艳众人,甚至改变世界运行的方式。今天,我们就来盘点那些让人拍案叫绝的算法,看看它们是如何用简洁的逻辑,解决复杂到让人抓狂的问题的!无论是快速排序的极简、哈希表的闪电查找,还是蒙特卡洛的随机艺术,它们都在用代码书写着“优雅”二字。比如 Java 的 HashMap,用哈希表存储键值对,无论数据多大,都能“秒查”。,效率吊打许多复杂算法。:选一个基准值,小的扔左边,大的扔右边,递归下去,排序完成。

微信公众号:互联网之路 751

SAP面试全过程(已拿offer)

周五打电话给我说过了SAP第一轮面试,第二轮要在下周四北京,这几天终于体会到了什么叫做重压下的感觉,越复习越虚,看别人的面经都感觉卧槽这问题也巨难了吧...连去北京可以见妹子这种事情都感觉一点心情都没有。面前准备固然是要有的,但关键是平时就要有料,多想想自己做的项目。当作一个给自己的提醒吧!

cloudray8580的专栏 4万+

IT世界里的“国境线”(芯片与算法篇)

首先分析下概念,对于芯片,相信大家已经比较了解,就不做过多的解释。我们说一下算法,虽然算法是应用在IT领域,但我相信学数学的同学,特别是学习计算数学的,对算法应该更加熟悉。记得在本科课程中,专门有一门课叫做“算法设计”。从概念上来讲,算法指的是解决问题的方法和流程,是一段逻辑,一系列解决问题的清晰指令。或者更通俗一点来讲,算法是从A到B,所有可能的计算方式。 一、 芯片与算法的关系 芯片和算法并不是独立或者对立的两个个体。芯片本身就集成了算法。算法是一种逻辑概念,芯片是算法的一种表现形式,软件也是算法的

weixin_49664622的博客 7018

精通八大排序算法系列:一、快速排序算法

精通八大排序算法系列:一、快速排序算法 作者 July 二零一一年一月四日------------------------------------------ 写此八大排序算法系列之前,先说点题外话。每写一篇文章,我都会遵循以下几点原则:一、保持版面的尽量清晰,力保排版良好。二、力争所写的东西,清晰易懂,图文并茂三、尽最大可能确保所写的东西精准,有实用价值。 ...

dinongxu8804的博客 3048

stable diffusioncontrolNet 预处理器/模型的下载及安装使用教程

首先说明,controlNet 的模型 不同于stable diffusion 模型,这一点一定要区分清楚。下面提供多个ControlNet 预处理器+ 专用模型的百度网盘下载链接,都是由群友整理贡献,但各自包含的版本不同,大家可自行选择。推荐下载紫色链接内的模型,fp16版文件更小,稍微新一些的controlnet插件还添加了对control-lora的支持(注意,要求controlnet插件的版本比12月16号新(1.1.423以上)才能正常识别),推荐下载;

代码简单说 Vue、JAVA、PHP、Node.js 熟练运用,接口、架构、性能全搞定。 3384

快速排序算法_基于位运算的快速排序算法

前言如果你准备看这篇文章,我就当你是懂快速排序算法原理的。下面是我在2018年10月3日想到的基于二进制位运算对正整数进行的一种快速排序算法,目前的代码只能对正整数进行有效的排序,当然,稍微修改一下就可以支持负数的排序了。后面会给出我用Julia语言实现的没有经过优化的代码和一些测试结果。如果您对此能有什么改进或者能帮吗优化一下代码,请告知我一下,我会非常感谢您。下面是此算法的思想和原理。2是一个...

weixin_39626162的博客 228

智能预测性维护AI系统实战效率提升:AI应用架构师的技巧分享

在工业领域,预测性维护(Predictive Maintenance, PdM)是降低停机损失、优化维护成本的关键手段。然而,现有系统往往面临三大效率瓶颈数据处理延迟:工业设备产生的海量实时数据(如传感器、PLC)需传输至云端处理,导致预警滞后;模型推理效率:复杂深度学习模型(如ResNet、Transformer)在边缘设备上推理时间长,无法满足实时要求;落地集成困难:与企业现有ERP、MES、SCADA系统对接繁琐,导致“模型好用但业务不用”的尴尬。本文从架构、数据、模型、落地架构设计。

AI天才研究院 744

yolov5改进之Fasternet主干网络替换

fasternet替换yolov5主干网络

qq_41920323的博客 5143

算法:快速排序的神奇优化

我在研究三路快速排序时,想出来了一个点子,使得非三路快速排序也可以高效排序大量重复元素的数据。 原理是这样的: 单次排序开始前,先设定一个状态为真 遇到等于基准值的值时,如果状态为真则与小于基准值时做相同的操作, 且无论状态为何值都对其进行取反并赋回原值。 这样可以保证遇到了重复的数据时,重复数据被均匀的分到了基准值两侧,从而避免了大量重复数据带来的严重划分不均匀,并提高了速度,减少了递归深度。 我将其称作交替快排。 以下为 交替快排、三路快排、普通快排 的不同数据情况的速度对比: 运行

qq_59283820的博客 313

Qt Creator 下载和安装

在线安装程序是一个小型的安装程序,它将在您的计算机上下载和安装 Qt Creator。离线安装程序是一个较大的安装包,您可以将其保存在本地,并在没有网络连接的情况下安装 Qt Creator。在 Qt 官方网站上,您可以找到 Qt Creator 的下载页面。Qt Creator 是一款跨平台的集成开发环境(IDE),用于开发基于 Qt 框架的应用程序。在这一步中,您可以选择是否安装 Qt Creator 的附加组件。一旦您完成了组件的选择,安装程序将开始将 Qt Creator 安装到您的计算机上。

HackLogic的博客 6817

快速排序算法真神奇

快速排序算法基于冒泡法的算法进行改进,我局的其实不妨可以称之为双向冒泡法。。。我局的亮点有几个,一个是类似于二叉树的结构,尽量减少了时间的层数,当然是通常情况下,二是双向,使用一个中间变量存储,并且作为中间量进行比较,由右向左刷出最小值,记录下标,空出下标量,在由左向右刷出最大值,记录下标量,这两种操作目的其实都是一种,那就留下合适的,移走不合适的,这样就保证了实现的同时在第一次排序中移动的次序最

qq_24433937的博客 312

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

C#排序算法大揭秘:数据世界的神奇整理术

冒泡排序简单但有点 “慢热”,适合小数据量的排序;快速排序聪明高效,是处理大数据量的好帮手,但在最坏情况下会 “掉链子”;归并排序稳定可靠,不管数据怎么 “捣乱”,它都能有序处理,就是稍微有点 “占空间”。了解这些排序算法的特点和原理,在编程时就能根据实际情况选择最合适的 “数据整理大师”,让程序高效运行!下次遇到排序问题,你知道该选谁了吧?

xcwzj123的专栏 925

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

快速排序算法

快速排序算法 堆排序和快速排序可以说是面试排序最容易考到的点了,本着非常应试的目的,温习一下快排的想法。 public static void quickSort(int []num,int start,int end) { if(start&amp;gt;=end) return; int key=num[start]; int low=start,high=end; while(lo...

qxdPx的博客 205

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

排序算法-快速排序的优化

跳转:排序算法 在看这个学习,有些没讲全,以下为补充。 快速排序优化 基准的选择 固定基准 基本算法本身每次切分是用的第一个,就叫固定基准,但如果序列本身有序或基本有序,则会使时间复杂度提升到O(N²),因为每次切分都用的第一个,要切分N次,每第 i 次比较 N - i 次。 随机基准 随机取基准,基准选的最差的概率就是N分之一,当然,选择最优基准的概率也是N分之一。避免了最坏情况的多次发生,算法的平均性能较好。 三数取中 选取数组开头,中间和结尾的元素,通过比较,选择中间的值作为快排的基准。比较稳定,但是

Tj的博客 790

对快速排序的一种神奇优化

博客内容是我在学习中突然想到的一个点子,就留下个记录吧。 排序算法大体上分为两类,一种是基于比较的排序,另一种是基于非比较的排序。基于比较的排序就是需要经过关键字多次的对比,对关键字进行交换以实现排序的目的。(像选择排序,归并排序,冒泡排序等等)非比较的不在赘述。下面我的改进策略也是对基于比较排序的改进。 距离思想 排序的实质其实就是按照某个标准,让关键字站成一排(不是废话)。也就是说如果确定一个标准的话,我们是可以计算两个关键字之间的距离的。比如把 2,3,4,5,1,7,8,9,序列按照从小到大的顺序

qq_45752106的博客 226

算法基础-快速排序

与 归并排序 一样, 快速排序 也使用了 分治思想(divide-and-conquer paradigm). 对于包含n个元素的数组来说, 快速排序是一种 最坏情况时间复杂度 O(n2), 平均时间复杂度 O(n*lgn). 1 快速排序描述 下面是对一个子数组 A[p..r] 进行快速排序的分治过程: 分解: 数组 A[p..r] 被划分为两个(可能为空)子数组 A[p..q-1] 和 A[q+1..r] , 使得 A[p..q-1] 中的每一个元素都小于等于 A[q] , 而 A[q] 也小于等于 A

四年时光 306

快速排序c语言_基于位运算的快速排序算法

前言如果你准备看这篇文章,我就当你是懂快速排序算法原理的。下面是我在2018年10月3日想到的基于二进制位运算对正整数进行的一种快速排序算法,目前的代码只能对正整数进行有效的排序,当然,稍微修改一下就可以支持负数的排序了。后面会给出我用Julia语言实现的没有经过优化的代码和一些测试结果。如果您对此能有什么改进或者能帮吗优化一下代码,请告知我一下,我会非常感谢您。下面是此算法的思想和原理。2是一个...

weixin_39713814的博客 118

【数据结构与算法】快速排序:让数据排序变得飞快!

文章目录目录引言一. 快速排序的基本思想二. 快速排序实现主框架三.寻找基准值的几种方法hoare版本挖坑法前后指针版本兄弟们共勉 !!! 每篇前言在数据处理的魔法世界里,有一种算法如同一位技艺高超的魔术师,能在瞬间将杂乱无章的数据变得井井有条。它,就是快速排序(QuickSort)——一个既高效又充满魅力的排序算法。想象一下,你面对着一堆毫无规律的数字或字母,如何在最短的时间内将它们排列得整整齐齐?快速排序就是这样一位神奇的助手,它运用分治法的智慧,通过巧妙地选择一个基准元素,将复杂的问题分解成更小的子问

2401_85548793的博客 850

写一下快速排序和堆排序,两个简单又神奇的算法

快速排序 void quick_sort(int array[], int begin, int end) { if(end > begin) { int pivot = begin; int last_small = begin; int i = end; while(last_small != i) { if(array[i] <= array[pivot])

世界很大我很小 1285

[转载]十大编程算法助程序员走上高手之路

十大编程算法助程序员走上高手之路 转自:http://mobile.51cto.com/news-450017_all.htm 本文为大家梳理阐述了十种高效率的变成算法,熟练掌握的程序员可以借这些方法逐渐发展为高手,那么我们一起来探究一下是哪十种算法有这么神奇的效果。 AD:2014WOT全球软件技术峰会北京站 课程视频发布 11月21日-22日 与WOT技术大会...

J010101的博客 167

前端学习数据结构与算法系列(八):快速排序与三路快排

❝本文由图雀社区认证作者 「神奇的程序员」 写作而成,图雀社区将连载其「前端学习数据结构与算法系列」,点击阅读原文查看作者的「掘金链接」,感谢作者的优质输出,让我们的技术世界变得更加美好...

指尖泛出的繁华 359

排序算法学习之快速排序

快速排序 快速排序,简称快排,在排序中,快速排序其实就是我们前面认为最慢的冒泡排序的升级,它们都属于交换排序类。即快排也是通过不断比较和移动交换来实现排序的,不过它的实现,增大了记录的比较和移动的距离,将关键字较大的记录从前面直接移动到后面,关键字较小的从后面直接移动到前面,从而减少了总的比较次数和移动交换次数。 基本思想: 任取待排元素序列中的某元素中的作为基准值,按照该排序...

Mr_Garfield__的博客 546
下一篇: MySQL彻底卸载指南:让旧版本干干净净不留痕(手把手教学)
普通网友
博客等级 码龄2年 89粉丝 25原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值