堆排序算法:
① 大顶堆(小顶堆)的建立
从最后一个叶结点开始,如果它有兄弟节点(左节点与右节点),选择其中较大值。随之与其父亲节点进行对比,若比父亲 节点值大,则与之替换。直至根节点。
值得注意的是:在替换后,要保证该每个节点都比其父亲节点值来的小。
② 堆顶元素与堆尾元素互换
③ 舍去堆尾元素,形成新的堆
④ 堆中元素的个数是否为1。若为1,算法结束;否则,将新的堆进行排成大顶堆(小顶堆)【回第①步】。
# 堆的建立
def heap_build(array, parent, end):
"""
调整成大顶堆,初始堆时,从下往上;交换堆顶与堆尾后,从上往下调整
:param array: 列表的引用
:param parent: 父结点
:param end: 结束的下标
:return: 无
"""
left_child = 2 * parent + 1
if( left_child <= end):
# 当列表第一个是以下标0开始,结点下标为i,左孩子则为2*i+1,右孩子下标则为2*i+2;
# 若下标以1开始,左孩子则为2*i,右孩子则为2*i+1
left_child = 2 * parent + 1 # 左孩子的结点下标
# 当结点的右孩子存在,且大于结点的左孩子时
if left_child+1 <= end and array[left_child + 1] > array[left_child]:
left_child = left_child + 1 # 在左右孩子中,选取教大的
if array[left_child] > array[parent]:
array[left_child],array[parent] = array[parent],array[left_child]
parent = left_child
heap_build(array, parent, end)
def heap_sort(array): # 堆排序
# 先初始化大顶堆
first = len(array)//2 -1 # 最后一个有孩子的节点(//表示取整的意思)
end = len(array)-1
for i in range(first, -1, -1): # 从最后一个有孩子的节点开始往上调整
heap_build(array,i,end) # 初始化大顶堆
for i in range(end,-1,-1):
array[0],array[i] = array[i],array[0] #堆顶元素与堆尾元素互换
heap_build(array,0,i-1)
if __name__ == "__main__":
array = [16, 7, 3, 20, 17, 8]
print(array)
heap_sort(array)
print(array)