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

排序算法-python实现

排序算法-python实现


算法分类与核心特性

算法名称时间复杂度(平均)最佳情况最坏情况空间复杂度稳定性原地排序适用场景
冒泡排序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(n log n)O(n log n)O(n²)O(log n)大数据通用排序
归并排序O(n log n)O(n log n)O(n log n)O(n)稳定排序需求(如链表结构)
堆排序O(n log n)O(n log n)O(n log n)O(1)原地排序(服务器TPS测试)
计数排序O(n+k)O(n+k)O(n+k)O(k)小范围整数排序(传感器数据)

分算法详解

1. 冒泡排序(Bubble Sort)

def bubble_sort(arr):# 获取数组长度n = len(arr)# 外层循环,控制排序轮数for i in range(n):# 标记当前轮是否发生了交换swapped = False# 内层循环,控制每轮排序的次数for j in range(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
  • 核心优化:提前终止机制
  • 嵌入式适配:STM32内存受限场景下的原地排序
  • 测试用例
assert bubble_sort([5,3,8,1]) == [1,3,5,8]  # 标准用例 
assert bubble_sort([-5,0,3]) == [-5,0,3]    # 负数场景

2. 插入排序(Insertion Sort)

def insertion_sort(arr):for i in range(1, len(arr)):# 从第二个元素开始遍历数组key = arr[i]# 当前要排序的元素j = i - 1# 初始化 j 为当前元素的前一个索引# 将大于 key 的元素后移while j >= 0 and key < arr[j]:arr[j + 1] = arr[j]# 将当前元素向后移动一位j -= 1# 将索引 j 向前移动一位# 插入 keyarr[j + 1] = key# 将 key 插入到正确的位置return arr
  • 性能优化:二分查找插入位置
  • 项目关联:LVGL库移植中的触摸坐标排序
  • 边界处理j >=0防止数组越界

3. 选择排序(Selection Sort)

def selection_sort(arr):"""选择排序实现(原地排序,内存敏感场景优选)Args:arr (list): 待排序的列表Returns:list: 排序后的列表Example:>>> selection_sort([64, 25, 12, 22, 11])[11, 12, 22, 25, 64]"""n = len(arr)for i in range(n):min_idx = i  # 初始化最小元素索引# 在未排序部分寻找最小元素for j in range(i+1, n):if arr[j] < arr[min_idx]:min_idx = j# 将找到的最小元素与第一个未排序元素交换arr[i], arr[min_idx] = arr[min_idx], arr[i]return arr
  • 核心特性
    • 原地排序:空间复杂度O(1),适合嵌入式系统
    • 时间复杂度:O(n²)(无论最好/最坏情况)
    • 非稳定排序:可能改变相等元素的相对顺序
    • 交换次数最少:只有n次交换(适合写操作昂贵的场景)

4. 快速排序(Quick Sort)

def quick_sort(arr):# 如果数组长度为0或1,直接返回数组if len(arr) <= 1:return arr# 选择第一个元素作为基准点pivot = arr[0]# 将小于基准点的元素放在left列表中for i in range(1, len(arr)):key = arr[i]j = i - 1# 将大于 key 的元素后移while j >= 0 and key < arr[j]:arr[j + 1] = arr[j]j -= 1# 插入 keyarr[j + 1] = keyreturn arr
  • 三数取中改进:避免最坏O(n²)情况
  • 服务器测试:网卡打流测试数据的快速切分

5. 归并排序(Merge Sort)

def merge_sort(arr):"""归并排序实现(分治策略,稳定排序)Args:arr (list): 待排序的列表Returns:list: 排序后的列表Example:>>> merge_sort([3, 6, 8, 10, 1, 2, 1])[1, 1, 2, 3, 6, 8, 10]"""# 基本结束条件:单元素数组直接返回if len(arr) <= 1:return arr# 分治阶段:递归分解mid = len(arr) // 2left_half = merge_sort(arr[:mid])  # 排序左半部right_half = merge_sort(arr[mid:])  # 排序右半部# 合并阶段:将两个有序数组合并merged = []i = j = 0# 比较两个数组元素并合并while i < len(left_half) and j < len(right_half):if left_half[i] <= right_half[j]:merged.append(left_half[i])i += 1else:merged.append(right_half[j])j += 1# 添加剩余元素merged.extend(left_half[i:])merged.extend(right_half[j:])return merged
  • 核心特性
    • 稳定排序:保持相等元素的相对顺序
    • 分治策略:递归分解+有序合并
    • 链表适配:特别适合链表结构排序(无需额外空间)

6. 堆排序(Heap Sort)

def _heapify(arr, n, i):"""维护堆结构"""largest = ileft = 2 * i + 1  # 计算左子节点的索引right = 2 * i + 2  # 计算右子节点的索引# 如果左子节点存在且大于当前节点,则更新最大节点为左子节点if left < n and arr[left] > arr[largest]:largest = left# 如果右子节点存在且大于当前最大节点,则更新最大节点为右子节点if right < n and arr[right] > arr[largest]: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
  • 核心特性
    • 原地排序:空间复杂度O(1),适合嵌入式系统
    • 时间复杂度:O(n log n)(无论最好/最坏情况)
    • 非稳定排序:可能改变相等元素的相对顺序
    • 二叉堆结构:完全二叉树的数组表示

7. 计数排序(Counting Sort)

def counting_sort(arr):"""计数排序实现(非比较型排序,适用于小范围整数)Args:arr (list): 待排序的整数列表Returns:list: 排序后的列表Example:>>> counting_sort([4, 2, 2, 8, 3, 3, 1])[1, 2, 2, 3, 3, 4, 8]"""if not arr:return []# 确定数据范围min_val, max_val = min(arr), max(arr)range_size = max_val - min_val + 1# 创建计数数组count = [0] * range_size# 统计元素出现次数for num in arr:count[num - min_val] += 1# 重建排序数组sorted_arr = []for i in range(range_size):sorted_arr.extend([i + min_val] * count[i])return sorted_arr
  • 核心特性
    • 非比较型排序:突破O(n log n)下限
    • 时间复杂度:O(n+k),k为数值范围
    • 空间复杂度:O(k),需要额外存储空间
    • 稳定性:通过后进先出策略保持稳定

算法选择决策树

数据规模?
├─ 小规模(n<1000) → 插入排序
├─ 大规模 → 分治类
│   ├─ 需稳定 → 归并排序d
│   └─ 不需稳定 → 快速排序
└─ 特殊数据├─ 整数且集中 → 计数排序└─ 硬件相关 → 堆排序

排序算法-python实现


算法分类与核心特性

算法名称时间复杂度(平均)最佳情况最坏情况空间复杂度稳定性原地排序适用场景
冒泡排序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(n log n)O(n log n)O(n²)O(log n)大数据通用排序
归并排序O(n log n)O(n log n)O(n log n)O(n)稳定排序需求(如链表结构)
堆排序O(n log n)O(n log n)O(n log n)O(1)原地排序(服务器TPS测试)
计数排序O(n+k)O(n+k)O(n+k)O(k)小范围整数排序(传感器数据)

分算法详解

1. 冒泡排序(Bubble Sort)

def bubble_sort(arr):# 获取数组长度n = len(arr)# 外层循环,控制排序轮数for i in range(n):# 标记当前轮是否发生了交换swapped = False# 内层循环,控制每轮排序的次数for j in range(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
  • 核心优化:提前终止机制
  • 嵌入式适配:STM32内存受限场景下的原地排序
  • 测试用例
assert bubble_sort([5,3,8,1]) == [1,3,5,8]  # 标准用例 
assert bubble_sort([-5,0,3]) == [-5,0,3]    # 负数场景

2. 插入排序(Insertion Sort)

def insertion_sort(arr):for i in range(1, len(arr)):# 从第二个元素开始遍历数组key = arr[i]# 当前要排序的元素j = i - 1# 初始化 j 为当前元素的前一个索引# 将大于 key 的元素后移while j >= 0 and key < arr[j]:arr[j + 1] = arr[j]# 将当前元素向后移动一位j -= 1# 将索引 j 向前移动一位# 插入 keyarr[j + 1] = key# 将 key 插入到正确的位置return arr
  • 性能优化:二分查找插入位置
  • 项目关联:LVGL库移植中的触摸坐标排序
  • 边界处理j >=0防止数组越界

3. 选择排序(Selection Sort)

def selection_sort(arr):"""选择排序实现(原地排序,内存敏感场景优选)Args:arr (list): 待排序的列表Returns:list: 排序后的列表Example:>>> selection_sort([64, 25, 12, 22, 11])[11, 12, 22, 25, 64]"""n = len(arr)for i in range(n):min_idx = i  # 初始化最小元素索引# 在未排序部分寻找最小元素for j in range(i+1, n):if arr[j] < arr[min_idx]:min_idx = j# 将找到的最小元素与第一个未排序元素交换arr[i], arr[min_idx] = arr[min_idx], arr[i]return arr
  • 核心特性
    • 原地排序:空间复杂度O(1),适合嵌入式系统
    • 时间复杂度:O(n²)(无论最好/最坏情况)
    • 非稳定排序:可能改变相等元素的相对顺序
    • 交换次数最少:只有n次交换(适合写操作昂贵的场景)

4. 快速排序(Quick Sort)

def quick_sort(arr):# 如果数组长度为0或1,直接返回数组if len(arr) <= 1:return arr# 选择第一个元素作为基准点pivot = arr[0]# 将小于基准点的元素放在left列表中for i in range(1, len(arr)):key = arr[i]j = i - 1# 将大于 key 的元素后移while j >= 0 and key < arr[j]:arr[j + 1] = arr[j]j -= 1# 插入 keyarr[j + 1] = keyreturn arr
  • 三数取中改进:避免最坏O(n²)情况
  • 服务器测试:网卡打流测试数据的快速切分

5. 归并排序(Merge Sort)

def merge_sort(arr):"""归并排序实现(分治策略,稳定排序)Args:arr (list): 待排序的列表Returns:list: 排序后的列表Example:>>> merge_sort([3, 6, 8, 10, 1, 2, 1])[1, 1, 2, 3, 6, 8, 10]"""# 基本结束条件:单元素数组直接返回if len(arr) <= 1:return arr# 分治阶段:递归分解mid = len(arr) // 2left_half = merge_sort(arr[:mid])  # 排序左半部right_half = merge_sort(arr[mid:])  # 排序右半部# 合并阶段:将两个有序数组合并merged = []i = j = 0# 比较两个数组元素并合并while i < len(left_half) and j < len(right_half):if left_half[i] <= right_half[j]:merged.append(left_half[i])i += 1else:merged.append(right_half[j])j += 1# 添加剩余元素merged.extend(left_half[i:])merged.extend(right_half[j:])return merged
  • 核心特性
    • 稳定排序:保持相等元素的相对顺序
    • 分治策略:递归分解+有序合并
    • 链表适配:特别适合链表结构排序(无需额外空间)

6. 堆排序(Heap Sort)

def _heapify(arr, n, i):"""维护堆结构"""largest = ileft = 2 * i + 1  # 计算左子节点的索引right = 2 * i + 2  # 计算右子节点的索引# 如果左子节点存在且大于当前节点,则更新最大节点为左子节点if left < n and arr[left] > arr[largest]:largest = left# 如果右子节点存在且大于当前最大节点,则更新最大节点为右子节点if right < n and arr[right] > arr[largest]: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
  • 核心特性
    • 原地排序:空间复杂度O(1),适合嵌入式系统
    • 时间复杂度:O(n log n)(无论最好/最坏情况)
    • 非稳定排序:可能改变相等元素的相对顺序
    • 二叉堆结构:完全二叉树的数组表示

7. 计数排序(Counting Sort)

def counting_sort(arr):"""计数排序实现(非比较型排序,适用于小范围整数)Args:arr (list): 待排序的整数列表Returns:list: 排序后的列表Example:>>> counting_sort([4, 2, 2, 8, 3, 3, 1])[1, 2, 2, 3, 3, 4, 8]"""if not arr:return []# 确定数据范围min_val, max_val = min(arr), max(arr)range_size = max_val - min_val + 1# 创建计数数组count = [0] * range_size# 统计元素出现次数for num in arr:count[num - min_val] += 1# 重建排序数组sorted_arr = []for i in range(range_size):sorted_arr.extend([i + min_val] * count[i])return sorted_arr
  • 核心特性
    • 非比较型排序:突破O(n log n)下限
    • 时间复杂度:O(n+k),k为数值范围
    • 空间复杂度:O(k),需要额外存储空间
    • 稳定性:通过后进先出策略保持稳定

算法选择决策树

数据规模?
├─ 小规模(n<1000) → 插入排序
├─ 大规模 → 分治类
│   ├─ 需稳定 → 归并排序d
│   └─ 不需稳定 → 快速排序
└─ 特殊数据├─ 整数且集中 → 计数排序└─ 硬件相关 → 堆排序

相关文章:

  • C++入门实战--通讯录管理系统
  • 【闲谈】对于c++未来的看法
  • JAVA集合篇--深入理解ConcurrentHashMap图解版
  • git安装使用详细教程
  • MySQL之索引结构和分类深度详解
  • 零基础学习Redis(13) -- Java使用Redis命令
  • Java基础 6.22
  • 【学习笔记】深入理解Java虚拟机学习笔记——第10章 前端编译与优化
  • 系列一、windows中安装RabbitMQ
  • 硬件面经-具身机器人通用技术要求
  • 逻辑门电路Multisim电路仿真汇总——硬件工程师笔记
  • 信息安全管理与评估2025湖北卷路由部分答案
  • pyhton基础【14】函数四
  • 爬虫001----介绍以及可能需要使用的技术栈
  • multiprocessing.pool和multiprocessing.Process
  • DeepSeek:中国AI开源先锋的技术突破与行业革新
  • Unity中的Mathf.Clamp
  • 嵌入式软件面经(一)Q: 什么是Modbus协议?它有哪些特点?
  • C++ unordered_map基础概念、对象创建、赋值操作、大小操作、数据插入、数据删除、数据修改、代码练习 1 2
  • 面试150 加油站
  • wordpress建站 评测/自己个人怎样做电商
  • 烟台网站建设 烟台网亿网络/网盟推广平台
  • 这是我做的网站/百度优化是什么
  • 网站做不做301/如何制作网站最简单的方法
  • 网站建设微信公众号小程序app/网站seo怎么操作
  • 东莞哪里的网站建设效果好/seo与sem的区别与联系