各种排序算法时间复杂度分析和实现和优势

以下是各种排序算法的时间复杂度详细对比:

  1. 比较排序算法

O(n²) 复杂度算法

算法 平均情况 最好情况 最坏情况 空间复杂度 稳定性 说明

冒泡排序 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²) O(n log n) O(n²) O(1) ✗ 改进的插入排序

梳排序 O(n log n) O(n) O(n²) O(1) ✗ 冒泡排序的改进

O(n log n) 复杂度算法

算法 平均情况 最好情况 最坏情况 空间复杂度 稳定性 说明

快速排序 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) ✗ 原地排序,不稳定

TimSort O(n log n) O(n) O(n log n) O(n) ✓ Python/Java内置

  1. 非比较排序算法

线性复杂度算法

算法 平均情况 最好情况 最坏情况 空间复杂度 稳定性 适用条件

计数排序 O(n + k) O(n + k) O(n + k) O(k) ✓ k是数值范围

桶排序 O(n + k) O(n) O(n²) O(n + k) ✓ 数据均匀分布

基数排序 O(d·(n + k)) O(d·(n + k)) O(d·(n + k)) O(n + k) ✓ d是最大位数

  1. 详细分析

快速排序

python 复制代码
"""
时间复杂度分析:
- 最优情况:每次分区都能均匀划分
  T(n) = 2T(n/2) + O(n) = O(n log n)
  
- 最坏情况:每次选到最小或最大值作为枢纽
  T(n) = T(n-1) + O(n) = O(n²)
  
- 平均情况:O(n log n)

空间复杂度:递归栈深度 O(log n)
"""

归并排序

python 复制代码
"""
时间复杂度分析:
- 分治递归:T(n) = 2T(n/2) + O(n)
- 用主定理求解:O(n log n)
- 稳定且总是 O(n log n)

空间复杂度:需要额外数组 O(n)
"""

堆排序

python 复制代码
"""
时间复杂度分析:
- 建堆:O(n)
- 每次堆调整:O(log n)
- 总复杂度:O(n) + n·O(log n) = O(n log n)

空间复杂度:原地排序 O(1)
"""
  1. 实际性能对比

小规模数据 (n < 50)

复制代码
插入排序 > 选择排序 ≈ 冒泡排序 > 快速排序

原因:插入排序在小数据上常数因子小

中等规模数据 (50 < n < 1000)

复制代码
快速排序 > 归并排序 > 堆排序 > 希尔排序

大规模数据 (n > 10000)

复制代码
快速排序 > TimSort > 归并排序 > 堆排序

特定情况

· 基本有序数据:插入排序 O(n),TimSort O(n)

· 范围小的整数:计数排序 O(n + k)

· 外排序(内存不足):归并排序

· 需要稳定性:归并排序、TimSort

  1. Python中的排序实现

内置排序

python 复制代码
# Python的sorted()使用TimSort
sorted_list = sorted(data)  # O(n log n), 稳定

# list.sort()也是TimSort
data.sort()  # 原地排序

TimSort特点

python 复制代码
"""
TimSort = 归并排序 + 插入排序 + 优化

1. 将数组分成多个run(有序子序列)
2. 对小的run使用插入排序
3. 使用归并排序合并run
4. 自适应:利用已有顺序

复杂度:
- 最好:O(n)(已基本有序)
- 平均:O(n log n)
- 最坏:O(n log n)
- 空间:O(n)
"""
  1. 各算法代码实现
python 复制代码
def bubble_sort(arr):
    """冒泡排序 O(n²)"""
    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

def selection_sort(arr):
    """选择排序 O(n²)"""
    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

def insertion_sort(arr):
    """插入排序 O(n²) - 最好O(n)"""
    for i in range(1, len(arr)):
        key = arr[i]
        j = i-1
        while j >= 0 and key < arr[j]:
            arr[j+1] = arr[j]
            j -= 1
        arr[j+1] = key
    return arr

def merge_sort(arr):
    """归并排序 O(n log n)"""
    if len(arr) <= 1:
        return arr
    
    mid = len(arr) // 2
    left = merge_sort(arr[:mid])
    right = merge_sort(arr[mid:])
    
    result = []
    i = j = 0
    while i < len(left) and j < len(right):
        if left[i] <= right[j]:
            result.append(left[i])
            i += 1
        else:
            result.append(right[j])
            j += 1
    
    result.extend(left[i:])
    result.extend(right[j:])
    return result

def heap_sort(arr):
    """堆排序 O(n log n)"""
    def heapify(arr, n, i):
        largest = i
        left = 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)
    
    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

def counting_sort(arr):
    """计数排序 O(n + k)"""
    if not arr:
        return []
    
    max_val = max(arr)
    min_val = min(arr)
    range_size = max_val - min_val + 1
    
    count = [0] * range_size
    output = [0] * len(arr)
    
    # 计数
    for num in arr:
        count[num - min_val] += 1
    
    # 累加
    for i in range(1, range_size):
        count[i] += count[i-1]
    
    # 输出
    for i in range(len(arr)-1, -1, -1):
        idx = arr[i] - min_val
        output[count[idx] - 1] = arr[i]
        count[idx] -= 1
    
    return output
  1. 算法选择指南

根据需求选择:

· 通用排序:快速排序或TimSort

· 需要稳定:归并排序或TimSort

· 原地排序(内存少):堆排序或快速排序

· 小数据量:插入排序

· 整数,范围小:计数排序

· 数据基本有序:插入排序或TimSort

· 链表结构:归并排序

根据数据特征:

复制代码
数据特征              | 推荐算法
----------------------|------------
随机                  | 快速排序
基本有序              | 插入排序/TimSort
范围小的整数          | 计数排序
需要稳定排序          | 归并排序/TimSort
内存受限              | 堆排序
分布式/外排序         | 归并排序
  1. 性能测试示例
python 复制代码
import time
import random
import matplotlib.pyplot as plt

def benchmark_algorithms():
    """性能基准测试"""
    algorithms = {
        '冒泡排序': bubble_sort,
        '选择排序': selection_sort,
        '插入排序': insertion_sort,
        '快速排序': quick_sort_simple,
        '归并排序': merge_sort,
        '堆排序': heap_sort,
    }
    
    sizes = [100, 500, 1000, 5000, 10000]
    results = {name: [] for name in algorithms}
    
    for size in sizes:
        arr = random.sample(range(size * 10), size)
        
        for name, func in algorithms.items():
            if size > 5000 and name in ['冒泡排序', '选择排序', '插入排序']:
                # O(n²)算法太慢,跳过
                results[name].append(None)
                continue
            
            arr_copy = arr.copy()
            start = time.time()
            func(arr_copy)
            end = time.time()
            results[name].append(end - start)
    
    # 可视化
    plt.figure(figsize=(12, 6))
    for name, times in results.items():
        valid_times = [t for t in times if t is not None]
        valid_sizes = [sizes[i] for i, t in enumerate(times) if t is not None]
        if valid_times:
            plt.plot(valid_sizes, valid_times, marker='o', label=name)
    
    plt.xlabel('数据量')
    plt.ylabel('时间 (秒)')
    plt.title('排序算法性能对比')
    plt.legend()
    plt.grid(True)
    plt.show()

# benchmark_algorithms()  # 取消注释运行测试

这个总结应该能帮助你根据具体情况选择合适的排序算法!

相关推荐
TTGGGFF44 分钟前
Supertonic 部署与使用全流程保姆级指南(附已部署镜像)
开发语言·python
love530love1 小时前
升级到 ComfyUI Desktop v0.7.0 版本后启动日志报 KeyError: ‘tensorrt‘ 错误解决方案
开发语言·windows·python·pycharm·virtualenv·comfyui·comfyui desktop
落羽凉笙7 小时前
Python学习笔记(3)|数据类型、变量与运算符:夯实基础,从入门到避坑(附图解+代码)
笔记·python·学习
Quintus五等升7 小时前
深度学习①|线性回归的实现
人工智能·python·深度学习·学习·机器学习·回归·线性回归
ytttr8737 小时前
隐马尔可夫模型(HMM)MATLAB实现范例
开发语言·算法·matlab
天远Date Lab7 小时前
Python实战:对接天远数据手机号码归属地API,实现精准用户分群与本地化运营
大数据·开发语言·python
哈里谢顿8 小时前
Python异常链:谁才是罪魁祸首?一探"The above exception"的时间顺序
python
zaiyang遇见8 小时前
【基础排序】USACO Bronze 2016 January - Angry Cows
排序算法·模拟·信息学奥赛·程序设计竞赛·函数封装·usaco
点云SLAM8 小时前
凸优化(Convex Optimization)理论(1)
人工智能·算法·slam·数学原理·凸优化·数值优化理论·机器人应用
哈里谢顿8 小时前
验证 list() 会调用 `__len__` 方法的深度解析
python·django