返回

排序算法详解:轻松攻破LeetCode中的排序难题

闲谈

掌握 LeetCode 排序算法的终极指南

作为一名程序员,掌握排序算法对于解决众多数据处理问题至关重要。本文将深入探讨 LeetCode 上最常见的 9 种排序算法,从基础的冒泡排序到高级的基数排序,帮助你全面提升算法技能。

1. 冒泡排序:简单易懂,基础扎实

冒泡排序是一种最简单直观的排序算法,它反复比较相邻元素,将较大的元素向后“冒泡”,直至数组有序。其时间复杂度为 O(n^2),空间复杂度为 O(1)。

def bubble_sort(arr):
    for i in range(len(arr) - 1):
        for j in range(len(arr) - i - 1):
            if arr[j] > arr[j + 1]:
                arr[j], arr[j + 1] = arr[j + 1], arr[j]

2. 选择排序:选出最优,逐个击破

选择排序是一种基于比较的排序算法,它反复从数组中选择最小的元素,并将其放在数组的开头。其时间复杂度为 O(n^2),空间复杂度为 O(1)。

def selection_sort(arr):
    for i in range(len(arr) - 1):
        min_index = i
        for j in range(i + 1, len(arr)):
            if arr[j] < arr[min_index]:
                min_index = j
        arr[i], arr[min_index] = arr[min_index], arr[i]

3. 插入排序:有序渐进,逐个插入

插入排序是一种基于比较的排序算法,它通过将每个元素逐个插入到前面的有序序列中,从而实现对整个数组的排序。其时间复杂度为 O(n^2),空间复杂度为 O(1)。

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

4. 归并排序:分而治之,有序融合

归并排序是一种基于分治的排序算法,它通过将数组划分为较小的子数组,对子数组进行排序,然后合并子数组以得到最终的排序结果。其时间复杂度为 O(n log n),空间复杂度为 O(n)。

def merge_sort(arr):
    if len(arr) <= 1:
        return arr

    mid = len(arr) // 2
    left_half = merge_sort(arr[:mid])
    right_half = merge_sort(arr[mid:])

    return merge(left_half, right_half)

def merge(left, right):
    merged = []
    left_index = 0
    right_index = 0

    while left_index < len(left) and right_index < len(right):
        if left[left_index] <= right[right_index]:
            merged.append(left[left_index])
            left_index += 1
        else:
            merged.append(right[right_index])
            right_index += 1

    merged.extend(left[left_index:])
    merged.extend(right[right_index:])

    return merged

5. 快速排序:随机枢纽,高效分割

快速排序是一种基于分治的排序算法,它通过选择一个枢纽元素,将数组划分为左右两个子数组,然后对子数组进行递归排序。其时间复杂度为 O(n log n),空间复杂度为 O(log n)。

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)

6. 堆排序:构建堆结构,逐个取出最大值

堆排序是一种基于堆的数据结构的排序算法,它通过将数组构建成一个二叉堆,然后逐个取出堆顶元素,从而实现对整个数组的排序。其时间复杂度为 O(n log n),空间复杂度为 O(1)。

def heap_sort(arr):
    n = len(arr)

    # Build a max heap
    for i in range(n, -1, -1):
        heapify(arr, n, i)

    # Sort the array
    for i in range(n - 1, 0, -1):
        arr[0], arr[i] = arr[i], arr[0]
        heapify(arr, i, 0)

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)

7. 计数排序:整数范围,高效计数

计数排序是一种基于计数的排序算法,它适用于整数范围有限的数组。其时间复杂度为 O(n + k),空间复杂度为 O(k),其中k为数组中最大元素与最小元素的差。

def counting_sort(arr):
    n = len(arr)
    max_value = max(arr)
    min_value = min(arr)
    range_value = max_value - min_value + 1
    count = [0] * range_value

    # Store the count of each element
    for i in range(n):
        count[arr[i] - min_value] += 1

    # Store the actual positions of each element in the output array
    output = []
    for i in range(range_value):
        while count[i] > 0:
            output.append(i + min_value)
            count[i] -= 1

    # Copy the output array back to the original array
    for i in range(n):
        arr[i] = output[i]

8. 桶排序:分桶归类,逐个排序

桶排序是一种基于比较的排序算法,它将数组划分为若干个桶,然后将每个元素放入相应的桶中。每个桶内再进行排序,最后将所有桶中的元素合并为一个有序的数组。其时间复杂度为 O(n + k),空间复杂度为 O(n + k),其中k为桶的数量。

def bucket_sort(arr):
    n = len(arr)
    max_value = max(arr)
    min_value = min(arr)
    bucket_size = (max_value - min_value) // n + 1
    buckets = [[] for _ in range(bucket_size)]

    # Distribute elements into buckets
    for i in range(n):
        bucket_index = (arr[i] - min_value) // bucket_size
        buckets[bucket_index].append(arr[i])

    # Sort each bucket
    for bucket in buckets:
        bucket.sort()

    # Concatenate all buckets into a single sorted array
    sorted_array = []
    for bucket in buckets:
        sorted_array.extend(bucket)

    return sorted_array

9. 基数排序:逐位比较,稳定排序

基数排序是一种基于计数的排序算法,它适用于整数范围有限的数组。其时间复杂度为 O(n * k),空间复杂度为 O(n + k),其中k为数组中最大元素的位数。

def radix_sort(arr):
    max_value = max(arr)
    exp = 1
    while max_value // exp > 0:
        counting_sort(arr, exp)
        exp *= 10

常见问题解答

  1. 哪些排序算法是最快的?
    快速排序和归并排序通常被认为是最快的排序算法。

  2. 哪种排序算法是最稳定的?
    基数排序和计数排序是稳定的排序算法,这意味着它们保留了相等元素的相对顺序。

  3. 哪种排序算法的空间复杂度最低?
    冒泡排序、