返回
排序算法:基数排序和堆排序,洞悉它们的奥妙
后端
2023-10-17 11:51:25
在计算机科学领域,排序算法扮演着至关重要的角色,它们被广泛应用于对数据进行整理和管理。在前几篇文章中,我们已经探讨了多种排序算法,包括冒泡排序、选择排序、插入排序、归并排序、快速排序和希尔排序。今天,我们将深入探究另外两种重要的排序算法:基数排序和堆排序。
基数排序
基数排序是一种非比较排序算法,它根据元素的个位数字进行排序,然后依次对更高位数字进行排序,直到所有数字都得到排序。对于基数为10的数字,基数排序将数字视为一系列十进制数字,并逐位进行排序。
基数排序算法的步骤如下:
- 确定要排序的数字中最大的数字。
- 按照最小的有效位数,将所有数字分组。
- 对每个组内的数字进行计数排序。
- 将分组后的数字合并回原始序列。
- 重复步骤2-4,直到所有位数都已排序。
堆排序
堆排序是一种基于堆数据结构的比较排序算法。堆是一种完全二叉树,其中每个节点的值都大于或等于其子节点的值。
堆排序算法的步骤如下:
- 将输入数组构建成一个最大堆。
- 将堆顶元素(最大元素)与最后一个元素交换。
- 将堆的大小减1,并对剩余的堆进行堆化(从堆顶向下调整)。
- 重复步骤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)
总结
基数排序和堆排序都是高效的排序算法,它们在不同的场景下都有着广泛的应用。通过深入理解这些算法的原理和实现,我们可以更好地选择适合特定问题的排序算法,从而提升程序的效率和性能。