该方法假设子树已经是堆,(这要求在访问结点之前,先访问子结点) 比较简单的方法是 从数组的较大序号到较小序号,实际上叶子结点没有子结点,因此从第一个分支结点开始访问
# encoding=utf-8
import logging
l = [i for i in range(10, 0, -1)]
def swap(a,b):
a=a^b
b=a^b
a=a^b
return a,b
def shiftdown(l, i):
logging.info("start shifdown %s" % (l[i]))
pos = i
# 不需要访问叶子结点
while pos < int(len(l)/2):
left = 2*pos + 1
# 找出子结点中值较小的结点的索引值
if 2*(pos+1) < len(l) and l[2*pos+1] > l[2*pos+2]:
left += 1
if l[pos] > l[left]:
# swap the element
l[pos], l[left] = swap(l[pos], l[left])
pos = left
else:
break
def heap_(l):
le = len(l)
for i in range(int(le/2)-1, -1, -1):
shiftdown(l, i)
r = []
def sort_(l):
end = len(l) - 1
while end > 0:
l[end], l[0] = swap(l[end], l[0])
r.append(l.pop())
shiftdown(l, 0)
end -= 1
r.append(l.pop())
heap_(l)
print (l)
sort_(l)
print(r)
最终输出
[1, 2, 4, 3, 6, 5, 8, 10, 7, 9]
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]