当前位置: 首页 > news >正文

【排序算法】八大经典排序算法详解

    • 一、直接选择排序(Selection Sort)
      • 算法思想
      • 算法步骤
      • 特性分析
    • 二、堆排序(Heap Sort)
      • 算法思想
      • 关键步骤
      • 特性分析
    • 三、直接插入排序(Insertion Sort)
      • 算法思想
      • 算法步骤
      • 特性分析
    • 四、希尔排序(Shell Sort)
      • 算法思想
      • 核心概念
      • 特性分析
    • 五、冒泡排序(Bubble Sort)
      • 算法思想
      • 优化策略
      • 特性分析
    • 六、快速排序(Quick Sort)
      • 算法思想
      • 关键步骤
      • 特性分析
    • 七、归并排序(Merge Sort)
      • 算法思想
      • 核心操作
      • 特性分析
    • 八、基数排序(Radix Sort)
      • 算法思想
      • 执行步骤
      • 特性分析
    • 九、排序算法对比
      • 算法优缺点对比
      • 算法复杂度对比
    • 总结

排序算法是计算机科学中最基础且应用最广泛的核心算法之一。本文将深入解析八种经典排序算法的原理、实现方式及适用场景,帮助读者全面掌握排序算法的核心知识。


一、直接选择排序(Selection Sort)

算法思想

通过不断选择剩余元素中的最小值,将其与当前未排序部分的起始位置交换,逐步构建有序序列。

算法步骤

  1. 从未排序序列中找到最小元素
  2. 将该元素与未排序序列的起始位置元素交换
  3. 将已排序序列的边界向右移动一位
  4. 重复上述过程直到整个序列有序
def selection_sort(arr):for i in range(len(arr)):min_idx = ifor j in range(i+1, len(arr)):if arr[j] < arr[min_idx]:min_idx = jarr[i], arr[min_idx] = arr[min_idx], arr[i]

特性分析

  • 时间复杂度:O(n²)(始终进行n(n-1)/2次比较)
  • 空间复杂度:O(1)
  • 稳定性:不稳定(交换可能破坏原有顺序)
  • 适用场景:教学演示、数据量极小时使用

二、堆排序(Heap Sort)

算法思想

利用堆这种数据结构的特性,通过构建大顶堆实现排序,将最大值依次交换到数组末尾。

关键步骤

  1. 建堆:从最后一个非叶子节点开始调整,构建大顶堆
  2. 排序阶段
    • 交换堆顶与当前末尾元素
    • 堆大小减1
    • 调整新堆顶使其满足堆性质
def heapify(arr, n, i):largest = il = 2 * i + 1r = 2 * i + 2if l < n and arr[l] > arr[largest]:largest = lif r < n and arr[r] > arr[largest]:largest = rif 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)

特性分析

  • 时间复杂度:O(n log n)
  • 空间复杂度:O(1)
  • 稳定性:不稳定
  • 优势:适合处理海量数据,不需要递归栈
  • 应用场景:实时数据流处理、优先级队列实现

三、直接插入排序(Insertion Sort)

算法思想

将待排序元素逐个插入到已排序序列的适当位置,类似整理扑克牌的过程。

算法步骤

  1. 从第一个元素开始视为已排序序列
  2. 取出下一个元素,在已排序序列中从后向前扫描
  3. 找到第一个小于等于当前元素的节点,插入其后
  4. 重复步骤2-3直到所有元素处理完成
def insertion_sort(arr):for i in range(1, len(arr)):key = arr[i]j = i-1while j >=0 and key < arr[j] :arr[j+1] = arr[j]j -= 1arr[j+1] = key

特性分析

  • 最佳时间复杂度:O(n)(已排序情况)
  • 平均时间复杂度:O(n²)
  • 空间复杂度:O(1)
  • 稳定性:稳定
  • 适用场景:小规模数据(n ≤ 1000)、基本有序数据

四、希尔排序(Shell Sort)

算法思想

通过将原始列表分割成多个子序列进行插入排序,随着增量逐渐减小,最终实现整体有序。

核心概念

  • 增量序列:确定子序列划分方式的间隔序列(常用Hibbard增量)
  • 分组插入:对每个增量间隔形成的子序列进行插入排序
def shell_sort(arr):n = len(arr)gap = n // 2while gap > 0:for i in range(gap, n):temp = arr[i]j = iwhile j >= gap and arr[j-gap] > temp:arr[j] = arr[j-gap]j -= gaparr[j] = tempgap //= 2

特性分析

  • 时间复杂度:O(n^1.3) ~ O(n²)(取决于增量序列)
  • 空间复杂度:O(1)
  • 稳定性:不稳定
  • 优势:中等规模数据高效排序
  • 历史意义:第一个突破O(n²)时间复杂度的排序算法

五、冒泡排序(Bubble Sort)

算法思想

通过相邻元素的比较和交换,使较大元素逐渐"浮"到数列顶端。

优化策略

  1. 提前终止:设置交换标志位检测是否已有序
  2. 边界优化:记录最后一次交换位置,减少无效比较
def bubble_sort(arr):n = len(arr)for i in range(n):swapped = Falsefor j in range(0, n-i-1):if arr[j] > arr[j+1]:arr[j], arr[j+1] = arr[j+1], arr[j]swapped = Trueif not swapped:break

特性分析

  • 最佳时间复杂度:O(n)(已排序情况)
  • 平均时间复杂度:O(n²)
  • 空间复杂度:O(1)
  • 稳定性:稳定
  • 应用价值:算法教学、简单场景应用

六、快速排序(Quick Sort)

算法思想

采用分治策略,通过选定基准元素将数组划分为两个子数组,递归排序。

关键步骤

  1. 基准选择:通常选第一个/中间/随机元素
  2. 分区操作:将小于基准的元素放在左侧,大于的放在右侧
  3. 递归处理:对左右子数组重复上述过程
def quick_sort(arr):if len(arr) <= 1:return arrpivot = 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(n log n)
  • 最坏时间复杂度:O(n²)(已排序数组+选择首元素为基准)
  • 空间复杂度:O(log n)(递归栈深度)
  • 稳定性:不稳定
  • 优化方向:三数取中法、尾递归优化、小数组切换插入排序

七、归并排序(Merge Sort)

算法思想

典型的分治算法,将数组递归分割到最小单位后合并有序子数组。

核心操作

  1. 分割阶段:递归地将数组二分至单个元素
  2. 合并阶段:将两个有序数组合并为新的有序数组
def merge_sort(arr):if len(arr) > 1:mid = len(arr)//2L = arr[:mid]R = arr[mid:]merge_sort(L)merge_sort(R)i = j = k = 0while i < len(L) and j < len(R):if L[i] < R[j]:arr[k] = L[i]i += 1else:arr[k] = R[j]j += 1k += 1while i < len(L):arr[k] = L[i]i += 1k += 1while j < len(R):arr[k] = R[j]j += 1k += 1

特性分析

  • 时间复杂度:O(n log n)
  • 空间复杂度:O(n)
  • 稳定性:稳定
  • 优势:适合链表结构、外部排序
  • 应用场景:大数据排序(内存不足时使用外部归并)

八、基数排序(Radix Sort)

算法思想

按位分割的非比较排序,从最低位(LSD)或最高位(MSD)开始进行多轮排序。

执行步骤

  1. 初始化10个桶(0-9)
  2. 从最低位到最高位依次进行:
    • 分配:按当前位数字将元素放入对应桶
    • 收集:按桶顺序将元素放回原数组
  3. 重复直到处理完所有位数
def radix_sort(arr):max_num = max(arr)exp = 1while max_num // exp > 0:buckets = [[] for _ in range(10)]for num in arr:buckets[(num // exp) % 10].append(num)arr = [num for bucket in buckets for num in bucket]exp *= 10return arr

特性分析

  • 时间复杂度:O(nk)(k为最大位数)
  • 空间复杂度:O(n+k)
  • 稳定性:稳定(依赖桶排序的稳定性)
  • 限制条件:仅适用于整数排序
  • 优化技巧:结合计数排序、动态确定位数

九、排序算法对比

算法优缺点对比

算法最佳场景优势局限性稳定性
直接选择排序教学演示实现简单效率低下不稳定
堆排序内存敏感的大数据无递归栈溢出风险缓存局部性差不稳定
插入排序小规模有序数据自适应性能好大规模数据效率骤降稳定
希尔排序中等规模随机数据突破O(n²)屏障增量序列选择复杂不稳定
冒泡排序检测数据有序性实现简单效率最低稳定
快速排序通用排序场景平均性能最优最坏情况性能差不稳定
归并排序大数据外部排序稳定且时间复杂度优空间复杂度高稳定
基数排序固定范围整数排序线性时间复杂度数据类型限制稳定

算法复杂度对比

请添加图片描述

总结

理解这些基础排序算法不仅是掌握数据结构的关键,更是优化实际工程问题的基础。建议读者通过可视化工具(如 Visualgo)观察算法的执行过程,并尝试自己实现不同版本的排序算法来加深理解。

相关文章:

  • 17. LangChain流式响应与实时交互:打造“类ChatGPT“体验
  • 某修改版软件,已突破限制!
  • 中国发布Web3计划:区块链列为核心基础技术,不排除发展加密资产应用!
  • 攻防世界 - Web - Level 4 | Confusion1
  • HTTP协议:原理、应用与python实践
  • MySQL事务隔离级别详解
  • GD32F407单片机开发入门(二十二)红外避障传感器模块实战含源码
  • 深⼊理解指针(8)
  • 解决 Oracle EXPDP 無法鎖定 NFS 相關錯誤: ORA-27086 flock: No locks available
  • HTTP知识速通
  • Python 函数装饰器和闭包(装饰器基础知识)
  • 文献阅读篇#5:5月一区好文阅读,BFA-YOLO,用于建筑信息建模!(上)
  • 新一代机载相控阵雷达的发展
  • 「Mac畅玩AIGC与多模态12」开发篇08 - 使用自定义汇率查询插件开发智能体应用
  • 【 Node.js】 Node.js安装
  • Java 期中考试练习题
  • 【速写】prune与activate
  • 解决Win10虚拟机“网络连接不上”,“Ethernet0 网络电缆被拔出”的问题
  • PB的框架advgui反编译后控件无法绘制的处理(即导入pbx的操作步骤)
  • 【漫话机器学习系列】234.阈值类特征的方差分析(Thresholding Categorical Feature Variance)
  • 网红“丢那猩”丢石块闯祸,起哄游客难逃责任
  • AI世界的年轻人|他用影像大模型解决看病难题,“要做的研究还有很多”
  • 龚正盛秋平王晓真共同启动2025国际消费季暨第六届上海“五五购物节”
  • 受天气等影响SC8041航班三次备降延误超12小时,山航致歉
  • 视频丨英伟达总裁黄仁勋:美勿幻想AI领域速胜中国
  • 王毅谈金砖国家开展斡旋调解的经验和独特优势