(二叉)堆的定义

(二叉)堆是一个数组,可以被看成一个近似的完全二叉树。

  1. class MaxHeap:
  2. def __init__(self, nums: List[int]):
  3. self.size = len(nums)
  4. # 堆数组索引从1开始,方便left, right和parent的计算
  5. self.arr = [0 for _ in range(self.size + 1)]
  6. def _left(self, i):
  7. return 2 * i
  8. def _right(self, i):
  9. return 2 * i + 1
  10. def _parent(self, i):
  11. return i // 2
  12. # 假定arr[i]的以left(i)和right(i)为根的二叉树
  13. # 都是最大堆
  14. def max_heapify(self, i):
  15. size = self.size
  16. l, r = self._left(i), self._right(i)
  17. if l <= size and self.arr[l] > self.arr[i]:
  18. largest = l
  19. else:
  20. largest = i
  21. if r <= size and self.arr[r] > self.arr[largest]:
  22. largest = r
  23. if largest != i:
  24. self.arr[i], self.arr[largest] = self.arr[largest], self.arr[i]
  25. # 交换过后可能不是最大堆,所以得维护堆的性质
  26. self.max_heapify(largest)

堆排序

步骤:

  1. 用给定的数组构建一个最大堆
  2. 将最大堆的根节点移动到末尾
  3. 除去末尾的结点并维护最大堆的性质
  4. 重复此过程 ```python def build_max_heap(nums: List[int]) -> MaxHeap: heap = MaxHeap(nums) for i in range(len(nums)):

    1. heap.arr[i+1] = nums[i]

    默认叶节点是符合最大堆的性质

    for i in range(heap.size // 2, 0, -1):

    1. heap.max_heapify(i)

    return heap

def heap_sort(nums):

  1. # 也可以原地排序,不过得修改left(i),right(i)和parent(i)
  2. heap = build_max_heap(nums)
  3. for i in range(heap.size, 1, -1):
  4. heap.arr[1], heap.arr[i] = heap.arr[i], heap.arr[1]
  5. heap.size -= 1
  6. heap.max_heapify(1)
  7. ret = heap.arr[1:]
  8. return ret

```

性能分析

时间复杂度:

  • max_heapify()堆排序 - 图1堆排序 - 图2为堆的高度)
  • build_max_heap()堆排序 - 图3
  • heap_sort()堆排序 - 图4