《我的第一本算法书》堆的Python实现
堆是一种树形结构,每个结点最多有两个子结点。
排列顺序是【1, 3, 6, 4, 8, 7】
相应下标号【0, 1, 2, 3, 4, 5】
可见下标号为 i 的结点左节点下标为 2i + 1,右结点下标为 2i + 2。
一、建立寻找左、右结点的方法:
def getLeft(arr, index):
position = 2 * index + 1
if len(arr) > position:
return arr[position]
else:
return None
def getRight(arr, index):
position = 2 * index + 2
if len(arr) > position:
return arr[position]
else:
return None
用List定义一个堆,添置一些数据,调用方法查询1、 3、 7的子结点:
array = [1, 3, 6, 4, 8, 7]
print(getLeft(array, array.index(1)), getRight(array, array.index(3)), getLeft(array, array.index(7)))
输出结果:
3 8 None
二、建立寻找父结点的方法:
def getHead(arr, index):
if index % 2 == 0:
# 偶数
if index == 0:
return None
return arr[int((index - 2)/2)]
else:
return arr[int((index - 1)/2)]
查询7的父结点
print(getHead(array, array.index(7)))
输出结果:
6
三、堆的排序
堆的存储规则是子结点必定大于父结点,添加结点的顺序是从最下方的左侧开始。
例如,上方实例堆添加一个数据5:
父结点大于子结点,交换它们的位置,直至满足排序规则:
建立排序方法:
def sortHeap(arr):
for index, value in enumerate(arr):
left = getLeft(arr, index)
if left:
if left < arr[index]:
arr[2 * index + 1], arr[index] = arr[index], left
right = getRight(arr, index)
if right:
if right < arr[index]:
arr[2 * index + 2], arr[index] = arr[index], right
四、增加数据
使用List的append方法。
array = [1, 3, 6, 4, 8, 7]
array.append(5)
print(array)
sortHeap(array)
print(array)
输出结果:
[1, 3, 6, 4, 8, 7, 5]
[1, 3, 5, 4, 8, 7, 6]
五、取出(删除)数据
堆取出最顶上的数据,然后将最后一位数据置顶
建立取出数据并重新排序的方法:
def heapPop(arr):
tmp = arr[0]
arr[0] = arr[-1]
arr.pop()
sortHeap(arr)
return tmp
调用方法:
print(heapPop(array), array)
输出结果:
1 [3, 4, 5, 6, 8, 7]