堆被看作是一个完全二叉树的数组对象,
满足条件:
大根堆:根节点最大的堆,升序排列构建大根堆。
小根堆:根节点最小的堆,降序排列构建小根堆。
这里以升序的堆排列作为讲解,
根据索引节点i计算,i为元素下标
父节点:(i - 1) // 2
左子节点:2i + 1
右子节点:2i + 2
python2.7.5
# _*_encoding:utf-8_*_
# 构建大根堆
def heapify_model(lists, index, length):
'''
lists:序列
index:父节点下标
length:list进行堆构建的最大长度范围,超出的元素不参与堆构建
'''
# length = len(lists)
left = 2 * index + 1 # 左子节点下标
right = 2 * index + 2 # 右子节点下标
maxindex = index # 默认父节点最大
# 左子节点大于最大节点,则替换最大节点
if length > left and lists[left] > lists[maxindex]:
maxindex = left
# 右子节点大于最大节点,则替换最大节点
if length > right and lists[right] > lists[maxindex]:
maxindex = right
# 判断父节点是否被替换,替换了说明父节点不是最大值,需要进行换位置
if maxindex != index:
# 替换父节点
lists[maxindex], lists[index] = lists[index], lists[maxindex]
# 递归,因为子节点与父节点进行了替换,所以要对子节点下面的堆进行调整,
heapify_model(lists,maxindex,length)
# 堆排序算法
def heapify_sort(lists):
length = len(lists)
# 首先需要构建大根堆,
# 构建大根堆需要从最后一个非叶子节点开始,从右至左,从下至上构建大根堆,调整架构
# 第一个非叶子节点的下标 length // 2 - 1,这里的堆是从下标0开始排列,
for i in range(length // 2 - 1,-1,-1): # 倒序,从右至左,从下至上
heapify_model(lists,i,length)
# --- 大根堆构建完成 ---
# 元素下沉构建大根堆
for j in range(0,length):
# 首元素(最大值)与最后一个元素换位置,
# 第m大的元素与lenght - m 换位置
# 这里是第一个最大值从下标0开始,所以要再减一
model_len = len(lists) - j - 1
lists[0], lists[model_len] = lists[model_len], lists[0]
# 换位置后lists最后一个元素即为最大值,
# 则再进行构建大根堆的时候,排除后面j + 1位,因为后面的j + 1 位元素已为有序排列
for k in range(model_len // 2 - 1,-1,-1): # 倒序,从右至左,从下至上
heapify_model(lists,k,model_len)
return lists
lt = [5,0,2,4,10,9,1]
print heapify_sort(lt)
–
参考:
https://www.cnblogs.com/liuqiyun/p/9415003.html