首页/新闻资讯/正文详情

十大经典排序算法原理与Python实现

发布时间:2026/11/3 13:26:16 来源:云帆数科 栏目:资讯中心
十大经典排序算法原理与Python实现
1. 排序算法基础与核心概念排序算法是计算机科学中最基础也是最重要的算法类别之一。作为数据处理的核心操作排序直接影响着数据库查询、搜索引擎结果、数据分析等众多应用的性能表现。在实际开发中我们经常需要对数据进行排序处理比如电商网站的商品价格排序、社交媒体的时间线排序等场景。排序算法主要分为两大类比较排序和非比较排序。比较排序通过比较元素间的大小关系来确定顺序而非比较排序则利用元素的特定属性如数值范围进行排序。常见的比较排序包括冒泡排序、快速排序等而非比较排序则有计数排序、基数排序等。时间复杂度是衡量排序算法效率的核心指标。O(n²)级别的算法如冒泡排序适合小规模数据而O(nlogn)级别的快速排序、归并排序则能高效处理大规模数据集。在实际应用中我们还需要考虑空间复杂度内存使用量和稳定性相等元素排序前后的相对位置是否改变等因素。提示算法稳定性在现实业务中非常重要。例如在电商平台先按价格排序再按评分排序时稳定的排序算法能保持相同评分商品的原始价格顺序。2. 十大经典排序算法深度解析2.1 冒泡排序(Bubble Sort)冒泡排序是最直观的排序算法之一其基本思想是通过相邻元素的比较和交换将较大的元素逐步冒泡到数组末端。具体实现时算法会进行多轮遍历每轮都将当前未排序部分的最大元素移动到正确位置。def bubble_sort(arr): n len(arr) for i in range(n-1): for j in range(n-i-1): if arr[j] arr[j1]: arr[j], arr[j1] arr[j1], arr[j] return arr冒泡排序的时间复杂度为O(n²)空间复杂度为O(1)。虽然效率不高但由于实现简单在小规模数据或近乎有序的数据集上仍有一定应用价值。优化版本可以添加标志位当某一轮没有发生交换时提前终止排序。2.2 选择排序(Selection Sort)选择排序的核心思想是每次从未排序部分选择最小或最大元素放到已排序部分的末尾。与冒泡排序相比它减少了元素交换次数但比较次数仍然相同。def selection_sort(arr): n len(arr) for i in range(n): min_idx i for j in range(i1, n): if arr[j] arr[min_idx]: min_idx j arr[i], arr[min_idx] arr[min_idx], arr[i] return arr选择排序的时间复杂度同样为O(n²)空间复杂度为O(1)。它是不稳定排序算法因为交换操作可能改变相等元素的相对位置。在实际应用中选择排序适用于数据量小且交换成本高的场景。2.3 插入排序(Insertion Sort)插入排序的工作方式类似于整理扑克牌将每个新元素插入到已排序部分的适当位置。对于近乎有序的数据集插入排序效率非常高甚至可以达到接近O(n)的时间复杂度。def insertion_sort(arr): n len(arr) for i in range(1, n): key arr[i] j i-1 while j 0 and arr[j] key: arr[j1] arr[j] j - 1 arr[j1] key return arr插入排序的平均时间复杂度为O(n²)最好情况已排序为O(n)空间复杂度为O(1)。它是稳定排序算法在小规模数据或部分有序数据上表现优异常被用作快速排序等高级算法的子过程。2.4 希尔排序(Shell Sort)希尔排序是插入排序的改进版通过将原始数组分割成若干子序列进行插入排序逐步缩小子序列间隔直至整个数组有序。这种分组策略使得元素能够快速移动到大致正确的位置。def shell_sort(arr): n len(arr) gap n // 2 while gap 0: for i in range(gap, n): temp arr[i] j i while j gap and arr[j-gap] temp: arr[j] arr[j-gap] j - gap arr[j] temp gap // 2 return arr希尔排序的时间复杂度取决于间隔序列的选择最佳情况下可达O(nlogn)空间复杂度为O(1)。它是不稳定排序算法适用于中等规模数据集在实际应用中性能通常优于简单的O(n²)排序算法。2.5 归并排序(Merge Sort)归并排序采用分治策略将数组递归地分成两半分别排序然后合并两个有序子数组。这种算法保证了最坏情况下O(nlogn)的时间复杂度但需要额外的O(n)空间。def merge_sort(arr): if len(arr) 1: mid len(arr) // 2 L arr[:mid] R arr[mid:] merge_sort(L) merge_sort(R) i j k 0 while i len(L) and j len(R): if L[i] R[j]: arr[k] L[i] i 1 else: arr[k] R[j] j 1 k 1 while i len(L): arr[k] L[i] i 1 k 1 while j len(R): arr[k] R[j] j 1 k 1 return arr归并排序是稳定排序算法特别适合处理链表结构和外部排序数据量太大无法全部加载到内存的情况。在Python的内置排序sorted()和Java的Collections.sort()中对于对象数组的排序就采用了归并排序的变体TimSort。2.6 快速排序(Quick Sort)快速排序是实际应用中最常用的排序算法同样采用分治策略。它选择一个基准元素(pivot)将数组分为小于基准和大于基准的两部分然后递归地对这两部分进行排序。def quick_sort(arr): if len(arr) 1: return arr pivot arr[len(arr)//2] left [x for x in arr if x pivot] middle [x for x in arr if x pivot] right [x for x in arr if x pivot] return quick_sort(left) middle quick_sort(right)快速排序的平均时间复杂度为O(nlogn)最坏情况已排序数组为O(n²)但通过合理选择pivot如三数取中法可以避免。它是原地排序算法空间复杂度O(logn)递归栈但不稳定。在实际应用中快速排序通常比其他O(nlogn)算法更快因为它的内循环更紧凑。注意上述实现为了清晰展示了快速排序的思想但实际应用中应该使用原地分区版本以减少空间使用这里的分区操作每次都会创建新列表。2.7 堆排序(Heap Sort)堆排序利用堆这种数据结构来实现排序。它首先将数组构建成最大堆然后反复取出堆顶元素最大值与末尾元素交换并重新调整堆直到整个数组有序。def heapify(arr, n, i): largest i l 2 * i 1 r 2 * i 2 if l n and arr[i] arr[l]: largest l if r n and arr[largest] arr[r]: largest r if largest ! i: arr[i], arr[largest] arr[largest], arr[i] heapify(arr, n, largest) def heap_sort(arr): n len(arr) for i in range(n//2 - 1, -1, -1): heapify(arr, n, i) for i in range(n-1, 0, -1): arr[i], arr[0] arr[0], arr[i] heapify(arr, i, 0) return arr堆排序的时间复杂度为O(nlogn)空间复杂度为O(1)。它是不稳定排序算法适合需要原地排序且对最坏情况时间复杂度有要求的场景。堆排序的一个实际应用是优先级队列的实现。2.8 计数排序(Counting Sort)计数排序是非比较排序算法适用于已知数据范围且范围不大的整数排序。它通过统计每个元素出现的次数然后计算每个元素在输出数组中的位置。def counting_sort(arr): max_val max(arr) m max_val 1 count [0] * m for a in arr: count[a] 1 i 0 for a in range(m): for c in range(count[a]): arr[i] a i 1 return arr计数排序的时间复杂度为O(nk)其中k是数据范围空间复杂度为O(k)。它是稳定排序算法但当数据范围很大时会消耗过多内存。计数排序常用于基数排序的子过程和数据统计场景。2.9 桶排序(Bucket Sort)桶排序将数据分到有限数量的桶里每个桶再分别排序通常使用其他排序算法。当数据均匀分布时效率很高。def bucket_sort(arr): bucket_size 10 max_val max(arr) min_val min(arr) bucket_count (max_val - min_val) // bucket_size 1 buckets [[] for _ in range(bucket_count)] for num in arr: buckets[(num - min_val) // bucket_size].append(num) arr.clear() for bucket in buckets: insertion_sort(bucket) arr.extend(bucket) return arr桶排序的平均时间复杂度为O(nk)最坏情况为O(n²)空间复杂度为O(nk)。它是稳定排序算法适用于数据分布均匀且范围已知的场景如浮点数排序。2.10 基数排序(Radix Sort)基数排序按照低位先排序然后收集再按照高位排序然后再收集依次类推直到最高位。通常使用计数排序作为子过程。def counting_sort_for_radix(arr, exp): n len(arr) output [0] * n count [0] * 10 for i in range(n): index arr[i] // exp count[index % 10] 1 for i in range(1, 10): count[i] count[i-1] i n - 1 while i 0: index arr[i] // exp output[count[index % 10] - 1] arr[i] count[index % 10] - 1 i - 1 for i in range(n): arr[i] output[i] def radix_sort(arr): max_val max(arr) exp 1 while max_val // exp 0: counting_sort_for_radix(arr, exp) exp * 10 return arr基数排序的时间复杂度为O(d(nk))其中d是数字位数k是基数通常为10空间复杂度为O(nk)。它是稳定排序算法特别适合整数和字符串排序如电话号码排序、字典排序等。3. 排序算法性能比较与选择策略3.1 时间复杂度对比下表总结了各排序算法的时间复杂度排序算法平均情况最好情况最坏情况空间复杂度稳定性冒泡排序O(n²)O(n)O(n²)O(1)稳定选择排序O(n²)O(n²)O(n²)O(1)不稳定插入排序O(n²)O(n)O(n²)O(1)稳定希尔排序O(nlogn)O(nlogn)O(n²)O(1)不稳定归并排序O(nlogn)O(nlogn)O(nlogn)O(n)稳定快速排序O(nlogn)O(nlogn)O(n²)O(logn)不稳定堆排序O(nlogn)O(nlogn)O(nlogn)O(1)不稳定计数排序O(nk)O(nk)O(nk)O(k)稳定桶排序O(nk)O(nk)O(n²)O(nk)稳定基数排序O(d(nk))O(d(nk))O(d(nk))O(nk)稳定3.2 实际应用选择指南在实际开发中选择排序算法时需要考虑以下因素数据规模小规模数据n100可选择简单排序插入、冒泡、选择大规模数据应选择O(nlogn)算法快速、归并、堆。数据特性近乎有序数据插入排序表现最佳大量重复元素三路快速排序数据范围有限计数排序或桶排序整数或字符串基数排序内存限制内存充足归并排序、快速排序内存受限堆排序、原地快速排序稳定性要求需要稳定排序归并排序、插入排序、冒泡排序不需要稳定排序快速排序、堆排序、选择排序实现复杂度快速实现使用语言内置排序函数如Python的sorted()特定需求根据场景选择或自定义实现经验分享在大多数通用排序场景中快速排序通常是默认选择因为它综合性能最好。但当需要稳定排序或处理链表结构时归并排序更合适。对于特定类型数据如小范围整数非比较排序可能效率更高。4. 排序算法优化技巧与常见问题4.1 算法优化实践混合排序策略结合不同排序算法的优势如快速排序在小规模子数组时切换到插入排序。Python的Timsort就是归并排序和插入排序的混合体。三路快速排序处理大量重复元素时将数组分为小于、等于和大于pivot三部分可显著提高效率。双轴快速排序Java的Arrays.sort()使用此方法选择两个pivot将数组分成三部分减少比较次数。自适应排序检测输入数据的特性如是否部分有序并自动选择最优策略。4.2 常见问题与解决方案栈溢出问题原因递归实现的快速排序在极端情况下如已排序数组递归深度过大解决使用尾递归优化或迭代实现随机化pivot选择设置递归深度限制性能下降问题原因选择了不适合数据特性的算法解决分析数据特征大小、分布、是否部分有序等后重新选择算法稳定性意外破坏原因错误地认为某些算法如改进的快速排序是稳定的解决明确需求是否需要稳定性选择对应算法并测试验证内存不足问题原因非原地排序算法处理大数据集时内存消耗过大解决改用原地排序堆排序、原地快速排序或外部排序算法4.3 测试与验证技巧边界测试空数组、单元素数组、已排序数组、逆序数组、全等元素数组性能测试对不同规模数据测试运行时间验证时间复杂度预期稳定性测试创建包含相等元素的对象数组验证排序前后相等元素的相对位置随机测试生成大量随机测试用例与标准库排序结果对比验证正确性# 排序算法验证示例 import random def test_sort(sort_func): # 空数组 assert sort_func([]) [] # 单元素数组 assert sort_func([1]) [1] # 已排序数组 assert sort_func([1,2,3,4,5]) [1,2,3,4,5] # 逆序数组 assert sort_func([5,4,3,2,1]) [1,2,3,4,5] # 随机数组 for _ in range(100): arr [random.randint(0, 100) for _ in range(100)] assert sort_func(arr.copy()) sorted(arr) print(All tests passed!) # 测试快速排序 test_sort(quick_sort)5. 现代排序算法发展与实际应用5.1 工业级排序实现分析主流编程语言的排序实现都采用了高度优化的混合算法Python的Timsort结合归并排序和插入排序适应不同数据特征是稳定排序时间复杂度O(nlogn)空间复杂度O(n)。Java的Dual-Pivot Quicksort用于基本类型排序双轴快速排序变种对象数组使用Timsort。C的Introsort结合快速排序、堆排序和插入排序防止快速排序的最坏情况。JavaScript引擎的排序不同引擎实现不同通常是小数组用插入排序大数组用快速排序或归并排序。5.2 特定领域排序优化数据库排序考虑磁盘I/O成本使用外部归并排序优化多路归并和缓冲区管理。图形处理器(GPU)排序利用并行计算能力实现bitonic排序、radix排序等并行算法。分布式排序MapReduce框架下的排序如Hadoop的TeraSort处理TB/PB级数据。内存数据库排序针对CPU缓存优化减少缓存未命中使用SIMD指令并行比较。5.3 排序算法的新发展并行排序算法利用多核CPU和GPU的并行计算能力如并行快速排序、样本排序。自适应排序算法根据输入数据特征自动选择最优策略如Introselect。机器学习辅助排序使用学习到的比较器或预测模型来优化排序过程。量子排序算法探索量子计算环境下的排序算法如量子快速排序。在实际工程中排序算法的选择和应用远比理论复杂需要综合考虑数据结构、内存访问模式、缓存利用率、分支预测等多方面因素。理解这些底层原理才能针对特定场景选择和实现最优的排序方案。

相关推荐

FAST-LIO源码精读:流形状态、ikd-Tree与工程避坑
FAST-LIO源码精读:流形状态、ikd-Tree与工程避坑

简介:围绕FAST-LIO论文与源码整理的个人理解文档,面向已具备ROS、C与SLAM基础、希望吃透LiDAR-IMU紧耦合框架的读者,可用于梳理算法脉络、对照代码理解实现细节。压缩包仅含1个docx,体积约5.09MB,内容按基础准备、FAST… · 2026/11/3 13:26:16

2024年TensorFlow生产实践:安装、部署与PyTorch选型指南
2024年TensorFlow生产实践:安装、部署与PyTorch选型指南

你要是现在打开技术讨论区,大概率会看到一种论调:TensorFlow 已经凉了,学它不如学 PyTorch。我在 2024 年还选择把 TensorFlow 写进生产环境,不是因为我守旧,而是因为我把模型从开发环境推到线上那条路走了太多次&… · 2026/11/3 13:26:16

RS-485电动窗帘中控协议解析:帧结构、CRC校验与联调实现
RS-485电动窗帘中控协议解析:帧结构、CRC校验与联调实现

简介:杜亚管状电机开合帘485协议文档面向智能家居集成商、电动窗帘控制开发者和中控调试人员,聚焦管状电机与外部设备之间的RS-485通讯规则与数据格式。内容围绕波特率9600bps、8位数据位、1位停止位、无校验等参数展开,说明以0x55为起始码的… · 2026/11/3 13:26:16

Hindsight揭秘:大模型调用链中的私有路由中间件
Hindsight揭秘:大模型调用链中的私有路由中间件

1. “Hindsight”不是产品名,而是开发者圈里一个心照不宣的隐喻 最近在几个技术社区和内部协作频道里,“hindsight”这个词频繁出现在报错日志、调试截图和 Slack 消息中——但它既不是 OpenAI 官方 SDK 的模块名,也不是 Anthropic 或 Google… · 2026/11/3 13:55:47

AB1568蓝牙耳机开发实战:启动链路、ANC调试与NVkey固化避坑指南
AB1568蓝牙耳机开发实战:启动链路、ANC调试与NVkey固化避坑指南

简介:这份PDF资料面向从事Airoha洛达AB1568蓝牙耳机固件与应用开发的工程师,系统梳理该芯片平台从底层启动到上层功能实现的开发要点,适合具备一定嵌入式与蓝牙协议基础、希望快速上手或查漏补缺的中级开发者。压缩包内为1个PDF文件&#xff… · 2026/11/3 13:55:47

MySQL管理工具全解析:从图形化到命令行
MySQL管理工具全解析:从图形化到命令行

1. MySQL管理工具全景解析 作为从业15年的数据库管理员,我见证了MySQL从一个小众数据库成长为全球最流行的开源关系型数据库的全过程。在这个过程中,各种MySQL管理工具如雨后春笋般涌现,它们极大提升了我们的工作效率。今天我就来系统梳理这些… · 2026/11/3 13:55:47

2024年TensorFlow实战:环境配置、框架对比与生产部署
2024年TensorFlow实战:环境配置、框架对比与生产部署

1. 2024年再看TensorFlow:它没有被取代,只是换了赛道 先说一个我自己的感受。我在深度学习框架里摸爬滚打了六七年,前三年基本是TensorFlow重度用户,后面四年变成TensorFlow和PyTorch双修。中间有一段时间,圈内几乎所有… · 2026/11/3 13:55:47

零基础本地部署Deepseek:Ollama与Chatbox实战指南
零基础本地部署Deepseek:Ollama与Chatbox实战指南

简介:这份PDF资料面向希望在个人电脑上离线运行DeepSeek模型的开发者与AI爱好者,聚焦本地化部署这一实操场景,兼顾入门与进阶需求。内容围绕Ollama框架展开,涵盖从官网下载安装、按硬件条件选择1.5B至671B不同参数规模模型&#x… · 2026/11/3 13:55:47

FPGA通过SPI配置高速ADC:时序本质与三线/四线实现避坑指南
FPGA通过SPI配置高速ADC:时序本质与三线/四线实现避坑指南

简介:面向FPGA开发者与硬件工程师的SPI配置ADC学习资料,聚焦FPGA通过SPI读写ADC内部寄存器这一实际工程问题,从通信原理到代码实现由浅入深展开,适合具备一定数字电路基础、希望掌握ADC配置时序的中级学习者参考。资源包共1个docx… · 2026/11/3 13:54:46

双极步进电机控制实战:DRV8818PWPR与PIC18F86K22驱动调试
双极步进电机控制实战:DRV8818PWPR与PIC18F86K22驱动调试

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/2 13:10:28

STM32F207ZG + DRV8818PWPR 步进电机驱动实战解析
STM32F207ZG + DRV8818PWPR 步进电机驱动实战解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/3 6:04:24

DRV8818PWPR+dsPIC30F4013工业级双极步进电机控制方案
DRV8818PWPR+dsPIC30F4013工业级双极步进电机控制方案

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/3 5:52:46

STM32F411RE与MAX14431实现SPI隔离:工业现场抗共模干扰实战
STM32F411RE与MAX14431实现SPI隔离:工业现场抗共模干扰实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/3 1:01:59

ESP32+大模型AI硬件开发:从Demo到产品的8个工程问题
ESP32+大模型AI硬件开发:从Demo到产品的8个工程问题

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/3 1:01:59

基于MAX14431BAEE+与PIC18F85J10的SPI隔离方案设计与实践
基于MAX14431BAEE+与PIC18F85J10的SPI隔离方案设计与实践

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/3 1:01:59

双极步进电机控制实战:DRV8818PWPR与PIC18F86K22驱动调试
双极步进电机控制实战:DRV8818PWPR与PIC18F86K22驱动调试

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/2 13:10:28

STM32F207ZG + DRV8818PWPR 步进电机驱动实战解析
STM32F207ZG + DRV8818PWPR 步进电机驱动实战解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/3 6:04:24

DRV8818PWPR+dsPIC30F4013工业级双极步进电机控制方案
DRV8818PWPR+dsPIC30F4013工业级双极步进电机控制方案

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/3 5:52:46

了解更多?预约专属演示

我们的顾问将为您一对一讲解产品与方案

企业微信二维码