堆排序:一种高效且稳定的排序算法

作者:梅琳marlin2024.04.07 12:26浏览量:85

简介:堆排序是一种基于二叉堆数据结构的排序算法,它能在O(nlogn)时间复杂度内完成排序,具有空间复杂度低和稳定性好的特点。本文将详细解释堆排序的原理、实现步骤,并通过实例和代码展示其在实际应用中的使用方法。

引言

在计算机科学中,排序算法是一类重要的算法,用于将一组数据按照特定的顺序(如升序或降序)进行排列。堆排序是一种高效、稳定的排序算法,广泛应用于数据处理、搜索引擎和操作系统等领域。

堆排序的原理

堆排序基于二叉堆数据结构,二叉堆是一种特殊的树形数据结构,满足堆属性:即每个节点的值都大于或等于(在最大堆中)或小于或等于(在最小堆中)其子节点的值。堆排序利用堆的性质,通过构建最大堆或最小堆,然后不断删除堆顶元素(最大或最小),并将剩余元素重新调整为堆,从而实现排序。

堆排序的实现步骤

  1. 构建最大堆:将待排序的数组转换为最大堆。从最后一个非叶子节点开始,从右至左、从下至上进行调整,确保每个节点都满足最大堆的性质。

  2. 删除堆顶元素:将堆顶元素(最大值)与堆尾元素交换,然后删除堆尾元素,此时堆的大小减一。

  3. 调整堆:对剩余元素重新进行最大堆的调整,确保堆的性质得以维持。

  4. 重复步骤2和3:重复执行步骤2和3,直到堆的大小减至1,此时数组已按降序排列。若要按升序排列,可在初始时构建最小堆。

实例演示

假设我们有一个待排序的数组 [4, 10, 3, 5, 1],我们将通过堆排序将其按升序排列。

  1. 构建最大堆
  1. 4 10 3 5 1

从最后一个非叶子节点开始调整,即元素3,此时满足最大堆的性质,无需调整。接下来调整元素4,它与子节点10和5比较,需要交换位置,得到:

  1. 10 4 3 5 1

继续调整元素10,得到:

  1. 10 5 3 4 1

最终得到最大堆:

  1. 10 5 3 4 1
  1. 删除堆顶元素:将堆顶元素10与堆尾元素1交换,然后删除堆尾元素,得到:
  1. 1 5 3 4

重新调整最大堆,得到:

  1. 5 1 3 4
  1. 重复步骤2:继续删除堆顶元素并调整堆,直到堆的大小为1。

经过上述步骤,我们得到排序后的数组:[1, 3, 4, 5, 10]

代码实现

以下是使用Python实现的堆排序算法:

```python
def heapify(arr, n, i):
largest = i # Initialize largest as root
l = 2 i + 1 # left = 2i + 1
r = 2 i + 2 # right = 2i + 2

  1. # See if left child of root exists and is greater than root
  2. if l < n and arr[i] < arr[l]:
  3. largest = l
  4. # See if right child of root exists and is greater than root
  5. if r < n and arr[largest] < arr[r]:
  6. largest = r
  7. # Change root, if needed
  8. if largest != i:
  9. arr[i], arr[largest] = arr[largest], arr[i] # swap
  10. # Heapify the root.
  11. heapify(arr, n, largest)

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

  1. # Build a maxheap.
  2. for i in range(n, -1, -1):
  3. heapify(arr, n, i)
  4. # One by one extract elements
  5. for i in range(n-1, 0, -1):
  6. arr[i], arr[0] = arr[0], arr[i] # swap
  7. heapify(arr, i, 0)

Test the function

arr =