堆的基本知识
-
堆:一种特殊的完全二叉树结构
- 完全二叉树:仅最后一层或次最后层有叶节点,且叶节点从左向右顺序排列
- 大根堆:任一节点都比其孩子节点大
- 小根堆:任一节点都比其孩子节点小
-
堆的向下调整
- 当根节点的左右子树都是堆而其本身不是堆时,通过一次向下调整来将其变换成一个堆
堆排序(以大根堆为例)
- 从最后一个有孩子的结点开始,依次调整,构造初始堆
- 得到初始堆的堆顶元素为最大元素
- 去掉堆顶,将堆的最后一个元素放到堆顶。通过一次向下调整重新构建堆
- 得到堆顶元素为第二大元素
- 依次重复,直到堆为空
代码实现
# ------------ Heap Sort ------------
def sift(list, low, high):
'''
:param list: list
:param low: root
:param high: the last index of element
:return:
'''
i = low
j = 2 * i + 1 # 指向i的左孩子
temp = list[low]
while j <= high: # 当j不越界
if j+1 <= high and list[j+1] > list[j]: # i有右孩子且右孩子比较大,让j指向右孩子
j = j + 1
if list[j] > temp: # 如果孩子节点中较大的一个大于取出的节点,将j位置的元素放到i位置上
list[i] = list[j]
i = j # i下移到j的位置,更新j
j = 2 * i + 1
else:
list[i] = temp
break
else:
list[i] = temp
def heap_sort(list):
n = len(list)
# 1. 建立堆
for i in range((n-2)//2, -1, -1): # 从最后一个非叶子节点开始,暨从最后一个叶子节点的父节点开始
sift(list, i, n-1)
# 2. 调整堆
for i in range(n-1, -1, -1): # 每次调整交换跟节点和当前未调整堆的最后一个元素
list[0], list[i] = list[i], list[0]
sift(list, 0, i-1)
li = list(range(20))
random.shuffle(li)
print(li)
heap_sort(li)
print(li)