数据结构与算法之排序算法

99 阅读4分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 18 天,点击查看活动详情

作者: 千石
支持:点赞、收藏、评论
欢迎各位在评论区交流

前言

本文内容来自我平时学习的一些积累,如有错误,还请指正

在题目实战部分,我将代码实现和代码解释设置在了解题思路的下方,方便各位作为参考刷题

一些话

本文内容来自我平时学习的一些积累,如有错误,还请指正

正文

冒泡排序(Bubble Sort)

冒泡排序是最简单的排序算法之一。它通过交换相邻的元素将最大的元素不断“冒泡”到数组的末尾。时间复杂度为 O(n^2),空间复杂度为 O(1)。

实现:

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

选择排序(Selection Sort)

选择排序是一种简单的排序算法。它通过每次选择最小的元素来将数组排序。时间复杂度为 O(n^2),空间复杂度为 O(1)。

实现:

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

插入排序(Insertion Sort)

插入排序是一种简单而有效的排序算法。它将数组分为已排序区间和未排序区间,每次从未排序区间取出一个元素插入到已排序区间中。时间复杂度为 O(n^2),空间复杂度为 O(1)。

实现:

def insertion_sort(arr):
    n = len(arr)
    for i in range(1, n):
        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

希尔排序(Shell Sort)

希尔排序是一种基于插入排序的快速排序算法。它通过比较跨越较大间隔的元素来排序,最后使用插入排序完成排序。时间复杂度为 O(n^1.3),空间复杂度为 O(1)。

实现:

def shell_sort(arr):
    n = len(arr)
    gap = n // 2
    while gap > 0:
        for i in range(gap, n):
            temp = arr[i]
            j = i
            while j >= gap and arr[j-gap] > temp:
                arr[j] = arr[j-gap]
                j -= gap
            arr[j] = temp
        gap //= 2
    return arr

归并排序(Merge Sort)

归并排序是一种基于分治策略的排序算法。它将数组分为两个子数组,递归地排序子数组,然后将已排序的子数组合并成一个有序的数组。时间复杂度为 O(nlogn),空间复杂度为 O(n)。

实现:

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):
    res = []
    i = j = 0
    while i < len(left) and j < len(right):
        if left[i] < right[j]:
            res.append(left[i])
            i += 1
        else:
            res.append(right[j])
            j += 1
    res += left[i:]
    res += right[j:]
    return res

快速排序(Quick Sort)

快速排序也是一种基于分治策略的排序算法。它通过选择一个基准值将数组分为左右两个子数组,然后递归地排序左右子数组。时间复杂度为 O(nlogn),空间复杂度为 O(logn)。

实现:

def quick_sort(arr):
    if len(arr) <= 1:
        return arr
    pivot = arr[0]
    left = [x for x in arr[1:] if x < pivot]
    right = [x for x in arr[1:] if x >= pivot]
    return quick_sort(left) + [pivot] + quick_sort(right)

堆排序(Heap Sort)

堆排序利用了堆的数据结构。它通过将数组构建成一个最大堆(或最小堆)来排序。时间复杂度为 O(nlogn),空间复杂度为 O(1)。

实现:

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[0], arr[i] = arr[i], arr[0]
        heapify(arr, i, 0)
    return arr

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)

计数排序(Counting Sort)

计数排序是一种线性时间复杂度的排序算法。它通过统计数组中每个元素出现的次数来排序。时间复杂度为 O(n+k),其中 k 是数组中元素的范围,空间复杂度为 O(k)。

实现:

def counting_sort(arr):
    n = len(arr)
    k = max(arr) + 1
    count = [0] * k
    for i in range(n):
              count[arr[i]] += 1
   for i in range(1, k):
       count[i] += count[i - 1]
   res = [0] * n
   for i in range(n - 1, -1, -1):
       res[count[arr[i]] - 1] = arr[i]
       count[arr[i]] -= 1
   return res

桶排序(Bucket Sort)

桶排序是一种分布式排序算法。它通过将数组分为若干个桶,将每个元素放入对应的桶中,然后对每个桶进行排序并按顺序输出元素。时间复杂度为 O(n),但需要额外的空间来存储桶。

实现:

def bucket_sort(arr, bucket_size=5):
    if len(arr) == 0:
        return arr min_val, max_val = min(arr), max(arr)
        bucket_count = (max_val - min_val) // bucket_size + 1
        buckets = [[] for _ in range(bucket_count)]
        for i in range(len(arr)):
            buckets[(arr[i] - min_val) // bucket_size].append(arr[i])
        res = []
        for i in range(bucket_count):
            if bucket_size == 1:
                bucket = buckets[i]
            else:
                bucket = bucket_sort(buckets[i], bucket_size - 1)
            res += bucket
        return res

基数排序(Radix Sort)

基数排序是一种按照数字位数排序的算法。它通过将数组按照个位、十位、百位等依次排序来得到最终结果。时间复杂度为 O(d*(n+k)),其中 d 是最大数字的位数,k 是每个位数的取值范围,空间复杂度为 O(n+k)。

实现:

def radix_sort(arr):
    if len(arr) == 0:
        return arr
    max_val = max(arr)
    digit = 0
    while max_val > 0:
        digit += 1
        max_val //= 10
    for d in range(digit):
        buckets = [[] for _ in range(10)]
        for num in arr:
            buckets[(num // 10 ** d) % 10].append(num)
        arr = []
        for bucket in buckets:
            arr += bucket
    return arr