以下是个人写的堆排序代码,原理我就不解释了(简单来说就是先建立一个大顶堆,然后进行顶点和最后节点的互换,互换之后需要重新建堆,两两比对,具体的话可以参照其他的,不过代码还是会于注释的。
#根据问题进行编码,由于数组下标是从0开始的,而树的节点从1开始,我们还需要引入一个辅助位置,Python提供的原始数据类型list实际上是一个线性(Array),
#由于我们需要在序列最左边追加一个辅助位,线性表这样做的话开销很大,需要把数组整体向右移动,所以list类型没有提供形如appendleft的函数,但是在一个
#链表里做这种操作就很简单了,Python的collections库里提供了链表结构deque,我们先使用它初始化一个无序序列:
from collections import deque #引用链表
def heap_adjust(data,start,length): #建一个大顶堆,上面最大,且父节点比左右两个子节点都要大
temp=data[start] #定义一个中间变量temp,代表父节点的值
left=start*2 #父节点下左节点的索引值
right=left+1 #父节点下右节点的索引值
while left<=length #主要在两两比对的时候需要用到while
if left<length and data[left]<data[right]: #判断左节点是否小于右节点,取节点的最大值
left=left+1 #如果右节点大,则把左节点的索引定位到右节点
if temp<data[left]: #判断子节点是否大于父节点
data[start],data[left]=data[left],data[start] #子节点与父节点的值互换
start=left #将父节点的索引指向子节点,主要用于两两比对,重新建堆的情况下
left=left*2 #将子节点的索引指向下一个子节点,主要用于两两比对,重新建堆的情况下
else:
break
def heap_sort(data):
data_length = len(data) - 1#由于在链表中多加了一个元素,所以长度需要减一
first_sort_count = int(data_length / 2) #第一个排序的长度
for i in range(first_sort_count):#使用向上比较的方法建立大顶堆
heap_adjust(data, first_sort_count - i, data_length)
for i in range(data_length - 1):#使用向下比较的方法建立大顶堆,重新找出最大值
data[1],data[data_length-i]=data[data_length-i],data[1]
heap_adjust(data, 1, data_length - i - 1)
return [data[i] for i in range(1, len(data))]
def main():
L = deque([50, 16, 30, 10, 60, 90, 2, 80, 70]) #把列表转换成链表
L.appendleft(0) #在列表的最左边加一个为0的数
print(heap_sort(L))
if __name__ == '__main__':
main()