常见的排序算法

一、基于比较的排序算法

基于比较的排序算法通过比较元素之间的大小来完成排序。

1.1 冒泡排序(Bubble Sort)

特点 :通过多次交换相邻元素,将最大(或最小)元素"冒泡"到序列末端。
时间复杂度

  • 最好:O(n)(输入数组已排序)
  • 最坏:O(n²)
    空间复杂度 :O(1)(原地排序)
    稳定性 :稳定
    适用场景:适合小规模、几乎有序的数据集。

实现代码(Python):

python 复制代码
def bubble_sort(arr):
    n = len(arr)
    for i in range(n):
        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

1.2 选择排序(Selection Sort)

特点 :每次从未排序部分选择最小元素,放到已排序部分末尾。
时间复杂度

  • 最好/最坏:O(n²)
    空间复杂度 :O(1)
    稳定性 :不稳定
    适用场景:适合数据量小、对稳定性无要求的场景。

实现代码:

python 复制代码
def selection_sort(arr):
    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

1.3 插入排序(Insertion Sort)

特点 :将序列分为已排序和未排序两部分,每次将未排序部分的第一个元素插入到已排序部分的合适位置。
时间复杂度

  • 最好:O(n)(输入数组已排序)
  • 最坏:O(n²)
    空间复杂度 :O(1)
    稳定性 :稳定
    适用场景:适合小规模或几乎有序的数据集。

实现代码:

python 复制代码
def insertion_sort(arr):
    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

1.4 快速排序(Quick Sort)

特点 :基于分治思想,通过选择一个"基准"(pivot),将数组划分为两部分,递归排序。
时间复杂度

  • 最好:O(n log n)
  • 最坏:O(n²)(输入数组完全逆序,或基准选择不当)
  • 平均:O(n log 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)

1.5 归并排序(Merge Sort)

特点 :基于分治思想,将数组递归分成两半,排序后再合并。
时间复杂度

  • 最好/最坏/平均:O(n log n)
    空间复杂度 :O(n)
    稳定性 :稳定
    适用场景:适合需要稳定排序的大规模数据。

实现代码:

python 复制代码
def merge_sort(arr):
    if len(arr) <= 1:
        return arr
    mid = len(arr) // 2
    left = merge_sort(arr[:mid])
    right = merge_sort(arr[mid:])
    return merge(left, right)

def merge(left, right):
    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

1.6 堆排序(Heap Sort)

特点 :利用堆数据结构的性质进行排序。
时间复杂度

  • 最好/最坏/平均:O(n log n)
    空间复杂度 :O(1)
    稳定性 :不稳定
    适用场景:适合需要原地排序的大规模数据。

实现代码:

python 复制代码
def heapify(arr, n, i):
    largest = i
    l = 2 * i + 1
    r = 2 * i + 2
    if l < n and arr[l] > arr[largest]:
        largest = l
    if r < n and arr[r] > arr[largest]:
        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(n log n)。

2.1 计数排序(Counting Sort)

特点 :通过统计每个元素出现的次数进行排序。
时间复杂度 :O(n + k)(k 为数据范围)
空间复杂度 :O(n + k)
稳定性 :稳定
适用场景:适合数据范围较小的整数排序。

实现代码(Python):

python 复制代码
def counting_sort(arr):
    if len(arr) == 0:
        return arr

    # 获取数组中的最大值和最小值
    max_val = max(arr)
    min_val = min(arr)

    # 创建计数数组,计数范围是最大值和最小值之间的数字
    range_of_elements = max_val - min_val + 1
    count = [0] * range_of_elements
    output = [0] * len(arr)

    # 统计每个元素的出现次数
    for num in arr:
        count[num - min_val] += 1

    # 计算累加计数
    for i in range(1, len(count)):
        count[i] += count[i - 1]

    # 从后往前填充输出数组,保证稳定性
    for num in reversed(arr):
        output[count[num - min_val] - 1] = num
        count[num - min_val] -= 1

    return output

2.2 基数排序(Radix Sort)

特点 :按位数进行排序,从低位到高位依次排列。
时间复杂度 :O(d*(n+k))(d 为位数,k 为基数范围)
空间复杂度 :O(n+k)
稳定性 :稳定
适用场景:适合对固定范围内的整数进行排序。

实现代码(Python):

python 复制代码
def counting_sort_radix(arr, exp):
    n = len(arr)
    output = [0] * n  # 输出数组
    count = [0] * 10  # 假设数字为0-9

    # 存储当前位数的计数
    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_radix(arr, exp)
        exp *= 10

    return arr

2.3 桶排序(Bucket Sort)

特点 :将数据分散到若干桶中,各桶内分别排序,然后合并结果。
时间复杂度 :O(n)(理想情况下)
空间复杂度 :O(n)
稳定性 :稳定(视桶内排序算法而定)
适用场景:适合数据分布均匀的情况。

实现代码(Python):

python 复制代码
def bucket_sort(arr):
    if len(arr) == 0:
        return arr

    # 找到数组中的最大值和最小值
    min_val = min(arr)
    max_val = max(arr)

    # 计算桶的数量
    bucket_count = len(arr)
    bucket_range = (max_val - min_val) / bucket_count

    # 创建桶
    buckets = [[] for _ in range(bucket_count)]

    # 将元素分配到桶中
    for num in arr:
        index = int((num - min_val) // bucket_range)
        if index == bucket_count:
            index -= 1
        buckets[index].append(num)

    # 对每个桶中的元素进行排序
    for i in range(bucket_count):
        buckets[i] = sorted(buckets[i])

    # 合并所有桶中的元素
    sorted_arr = []
    for bucket in buckets:
        sorted_arr.extend(bucket)

    return sorted_arr

总结

算法 时间复杂度(最坏) 时间复杂度(最好) 空间复杂度 稳定性 适用场景
冒泡排序 O(n²) O(n) O(1) 稳定 小规模或近似有序
选择排序 O(n²) O(n²) O(1) 不稳定 无需稳定性的简单场景
插入排序 O(n²) O(n) O(1) 稳定 小规模或近似有序
快速排序 O(n²) O(n log n) O(log n) 不稳定 大规模一般场景
归并排序 O(n log n) O(n log n) O(n) 稳定 大规模需要稳定
堆排序 O(n log n) O(n log n) O(1) 不稳定 原地排序需求
计数排序 O(n+k) O(n+k) O(n+k) 稳定 小范围整数
基数排序 O(d * (n + k)) O(d * (n + k)) O(n+k) 稳定 适合对固定范围内的整数进行排序
桶排序 O(n²) O(n + k) O(n) 稳定 适合数据分布均匀的情况
相关推荐
T.O.P113 分钟前
数据结构和算法
java·开发语言·数据结构
ling-455 分钟前
数据结构—查找
数据结构
重生之绝世牛码6 分钟前
Java设计模式 —— 【创建型模式】工厂模式(简单工厂、工厂方法模式、抽象工厂)详解
java·大数据·开发语言·设计模式·工厂方法模式·设计原则·工厂模式
DKPT7 分钟前
数据结构逻辑结构有哪些
开发语言·数据结构·笔记·学习·算法
测试盐28 分钟前
linux系统中常用文件&日常使用命令记录
linux·python
潜洋1 小时前
Spring Boot教程之十一:获取Request 请求 和 Put请求
java·开发语言·python
秋凉 づᐇ1 小时前
2024-11-25 二叉树的定义
数据结构·算法
Muisti1 小时前
P8723 [蓝桥杯 2020 省 AB3] 乘法表
算法·职场和发展·蓝桥杯
AskHarries1 小时前
一个高效的Java对象映射库Orika
java·开发语言·python