首先说堆,什么是堆?
堆(默认大根堆)有两个特点:1.堆都是完全二叉树 2.堆的父节点的值都大于其孩子节点的值
其次我们要生成一个堆,也就是我们要从堆的最后一个父节点(度不为0的节点,按层次遍历数)开始往前依次进行堆化,以此递归的生成大根堆。
def max_heapify(heap, heapSize, root):
"""堆化"""
left = 2*root + 1
right = 2*root + 2
max_node = root
if left < heapSize and heap[left] > heap[max_node]:
max_node = left
if right < heapSize and heap[right] > heap[max_node]:
max_node = right
if max_node != root:
heap[max_node], heap[root] = heap[root], heap[max_node]
max_heapify(heap, heapSize, max_node)
def build_max_heap(heap):
n = len(heap)
#从(heapSize -2)//2处开始调整,一直调整到第一个根节点
for i in range((n-2)//2, -1, -1):
max_heapify(heap, n, i)
return heap
有了一个堆后我们就开始进行堆排序,堆排序就是将堆的根节点与最后一个节点进行交换,因为已经是大根堆所以根节点一定是最大的值。交换后再将当前最后一个节点弹出,再把当前的二叉树堆化,以此规律进行下去,直到堆的所有元素均弹出。
def max_heapify(heap, heapSize, root):
left = 2*root + 1
right = 2*root + 2
#父节点i的左子节点在位置(2*i+1);
#父节点i的右子节点在位置(2*i+2);
max_node = root
if left < heapSize and heap[left] > heap[max_node]:
max_node = left
if right < heapSize and heap[right] > heap[max_node]:
max_node = right
if max_node != root:
heap[max_node], heap[root] = heap[root], heap[max_node]
max_heapify(heap, heapSize, max_node)
def build_max_heap(heap):
n = len(heap)
#从(heapSize -2)//2处开始调整,一直调整到第一个根节点
for i in range((n-2)//2, -1, -1):
max_heapify(heap, n, i)
return heap
#heap = [4, 10, 3, 5, 1, 2]
#heap = [50,16,30,10,60,90,2,80,70]
#build_max_heap(heap)
def heap_sort(heap):
heap = build_max_heap(heap)
n = len(heap)
alist = []
for i in range(n-1, -1, -1):
heap[0], heap[-1] = heap[-1], heap[0]
alist.append(heap.pop(-1))
max_heapify(heap, len(heap), 0)
#alist = alist + heap
return alist
heap = [50,16,30,10,60,90,2,80,70]
heap = [54,26,93,17,77,31,44,55,20]
heap_sort(heap)