Python排序算法详解:冒泡排序、快速排序与堆排序 - 完整教程与代码示例
- Python
- 2025-07-20
- 96
Python排序算法详解:冒泡排序、快速排序与堆排序
全面解析三种经典排序算法的原理、实现及优化方法
排序算法概述
排序算法是计算机科学中最基本也是最重要的算法类型之一。本教程将详细讲解Python中三种经典排序算法:冒泡排序、快速排序和堆排序。每种算法都有其独特的实现原理和适用场景。
冒泡排序
最简单直观的排序算法,时间复杂度O(n²)
快速排序
高效的分治排序算法,平均时间复杂度O(n log n)
堆排序
基于二叉堆的排序算法,时间复杂度O(n log n)
冒泡排序 (Bubble Sort)
算法原理
冒泡排序重复遍历待排序的数列,一次比较两个元素,如果它们的顺序错误就把它们交换过来。遍历数列的工作是重复地进行直到没有再需要交换的元素。
算法步骤
- 比较相邻的元素。如果第一个比第二个大,就交换它们两个
- 对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对
- 针对所有的元素重复以上的步骤,除了最后一个
- 重复步骤1~3,直到排序完成
算法分析
- 时间复杂度:O(n²)(最坏和平均情况)
- 空间复杂度:O(1)
- 稳定性:稳定
Python实现
def bubble_sort(arr): n = len(arr) # 遍历所有数组元素 for i in range(n): # 最后i个元素已经有序 for j in range(0, n-i-1): # 当前元素大于下一个元素则交换 if arr[j] > arr[j+1]: arr[j], arr[j+1] = arr[j+1], arr[j] return arr # 测试示例 data = [64, 34, 25, 12, 22, 11, 90] print("排序前:", data) print("排序后:", bubble_sort(data.copy()))
优化版本
添加一个标志位,如果某一轮没有发生交换,说明已经有序,可以提前结束
def optimized_bubble_sort(arr): n = len(arr) for i in range(n): swapped = False for j in range(0, n-i-1): if arr[j] > arr[j+1]: arr[j], arr[j+1] = arr[j+1], arr[j] swapped = True if not swapped: break return arr
快速排序 (Quick Sort)
算法原理
快速排序使用分治法策略来把一个序列分为两个子序列。步骤为:
- 从数列中挑出一个元素作为基准(pivot)
- 重新排序数列,所有比基准小的元素放在基准前面,所有比基准大的元素放在基准后面(相同的数可以到任一边)
- 递归地把小于基准的子数列和大于基准的子数列排序
算法特点
- 平均时间复杂度:O(n log n)
- 最坏时间复杂度:O(n²)(当输入已经排序时)
- 空间复杂度:O(log n)(递归调用栈)
- 不稳定排序算法
Python实现
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) # 测试示例 data = [10, 7, 8, 9, 1, 5, 3, 6, 2, 4] print("排序前:", data) print("排序后:", quick_sort(data.copy()))
原地分区版本
更高效的内存使用,不需要额外空间
def partition(arr, low, high): i = low - 1 pivot = arr[high] for j in range(low, high): if arr[j] <= pivot: i += 1 arr[i], arr[j] = arr[j], arr[i] arr[i+1], arr[high] = arr[high], arr[i+1] return i + 1 def quick_sort_inplace(arr, low=0, high=None): if high is None: high = len(arr) - 1 if low < high: pi = partition(arr, low, high) quick_sort_inplace(arr, low, pi-1) quick_sort_inplace(arr, pi+1, high) return arr
堆排序 (Heap Sort)
算法原理
堆排序是利用堆这种数据结构所设计的一种排序算法。堆是一个近似完全二叉树的结构,并同时满足堆的性质:子节点的键值总是小于(或大于)其父节点。
算法步骤
- 将待排序序列构建成一个最大堆(升序排序)
- 将堆顶元素(最大值)与末尾元素交换
- 减少堆的有效长度,重新调整结构使其满足堆定义
- 重复步骤2-3,直到整个序列有序
算法分析
- 时间复杂度:O(n log n)(所有情况)
- 空间复杂度:O(1)
- 不稳定排序算法
- 适合大数据量排序
Python实现
def heapify(arr, n, i): largest = i # 初始化最大值为根节点 left = 2 * i + 1 right = 2 * i + 2 # 如果左子节点存在且大于根节点 if left < n and arr[i] < arr[left]: largest = left # 如果右子节点存在且大于当前最大值 if right < n and arr[largest] < arr[right]: largest = right # 如果最大值不是根节点,则交换 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 # 测试示例 data = [12, 11, 13, 5, 6, 7, 3, 2, 8] print("排序前:", data) print("排序后:", heap_sort(data.copy()))
三种排序算法比较
算法 | 时间复杂度(平均) | 时间复杂度(最坏) | 空间复杂度 | 稳定性 | 适用场景 |
---|---|---|---|---|---|
冒泡排序 | O(n²) | O(n²) | O(1) | 稳定 | 小数据集或基本有序数据 |
快速排序 | O(n log n) | O(n²) | O(log n) | 不稳定 | 通用排序,大数据量 |
堆排序 | O(n log n) | O(n log n) | O(1) | 不稳定 | 大数据量,需要O(1)空间 |
排序算法选择建议
- 小数据集(n ≤ 10):冒泡排序或插入排序
- 通用排序:快速排序(平均性能最好)
- 需要稳定排序:归并排序(本教程未涉及)
- 需要O(1)空间复杂度:堆排序
- 数据基本有序:插入排序或冒泡排序
实际应用建议
Python内置的sorted()
函数和list.sort()
方法使用TimSort算法(归并排序和插入排序的混合),在大多数情况下是最优选择。
学习这些排序算法主要是为了理解算法设计原理,在实际开发中应优先使用内置排序函数。
本文由LiBin于2025-07-20发表在吾爱品聚,如有疑问,请联系我们。
本文链接:https://521pj.cn/20256049.html
发表评论