返回

排序算法:基数排序和堆排序,洞悉它们的奥妙

后端

在计算机科学领域,排序算法扮演着至关重要的角色,它们被广泛应用于对数据进行整理和管理。在前几篇文章中,我们已经探讨了多种排序算法,包括冒泡排序、选择排序、插入排序、归并排序、快速排序和希尔排序。今天,我们将深入探究另外两种重要的排序算法:基数排序和堆排序。

基数排序

基数排序是一种非比较排序算法,它根据元素的个位数字进行排序,然后依次对更高位数字进行排序,直到所有数字都得到排序。对于基数为10的数字,基数排序将数字视为一系列十进制数字,并逐位进行排序。

基数排序算法的步骤如下:

  1. 确定要排序的数字中最大的数字。
  2. 按照最小的有效位数,将所有数字分组。
  3. 对每个组内的数字进行计数排序。
  4. 将分组后的数字合并回原始序列。
  5. 重复步骤2-4,直到所有位数都已排序。

堆排序

堆排序是一种基于堆数据结构的比较排序算法。堆是一种完全二叉树,其中每个节点的值都大于或等于其子节点的值。

堆排序算法的步骤如下:

  1. 将输入数组构建成一个最大堆。
  2. 将堆顶元素(最大元素)与最后一个元素交换。
  3. 将堆的大小减1,并对剩余的堆进行堆化(从堆顶向下调整)。
  4. 重复步骤2-3,直到堆中只剩下一个元素。

比较和应用

基数排序和堆排序各有优缺点,它们的适用场景也有所不同。

  • 基数排序对于包含大量相同数字的数组非常高效,因为它的时间复杂度与输入数组中不同数字的数量成正比。
  • 堆排序的时间复杂度为O(nlogn),对于几乎有序的数组,它的效率很高。

示例代码

基数排序(Python)

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

def counting_sort(nums, exp):
    n = len(nums)
    output = [0] * n
    count = [0] * 10  # 0-9

    for i in range(n):
        index = nums[i] // exp
        count[index % 10] += 1

    for i in range(1, 10):
        count[i] += count[i - 1]

    i = n - 1
    while i >= 0:
        index = nums[i] // exp
        output[count[index % 10] - 1] = nums[i]
        count[index % 10] -= 1
        i -= 1

    for i in range(n):
        nums[i] = output[i]

堆排序(Python)

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

    # 构建最大堆
    for i in range(n // 2 - 1, -1, -1):
        heapify(nums, n, i)

    # 一个一个地将最大元素移到数组末尾
    for i in range(n - 1, 0, -1):
        nums[i], nums[0] = nums[0], nums[i]  # 交换最大元素和最后一个元素
        heapify(nums, i, 0)

def heapify(nums, n, i):
    largest = i
    left = 2 * i + 1
    right = 2 * i + 2

    if left < n and nums[left] > nums[largest]:
        largest = left

    if right < n and nums[right] > nums[largest]:
        largest = right

    if largest != i:
        nums[i], nums[largest] = nums[largest], nums[i]  # 交换
        heapify(nums, n, largest)

总结

基数排序和堆排序都是高效的排序算法,它们在不同的场景下都有着广泛的应用。通过深入理解这些算法的原理和实现,我们可以更好地选择适合特定问题的排序算法,从而提升程序的效率和性能。