【算法导论】第6章,堆排序
6.1 堆数据结构
是一个完全二叉树,从左向右填充。
有两个属性:树大小、有效数据长度。可以用数据表示,1 2 4 8 这种形式。
可以分为两种形式:最大堆和最小堆。最大堆:根节点不比叶子节点小。
最大堆:堆排序。最小堆:优先队列。
6.2 保持最大堆的性质
假设两个子堆都满足,只需要根节点依次换下去,复杂度O(lg n)
6.3 初始化堆
后半段都是叶子,在前半段从后往前,依次执行上述最大堆性质的操作,名义复杂度是O(n lg n),但是有更精确的计算,
在高度为h的节点为O(h), 因此为 n\sigma (h / 2^h),其复杂度为O(n)。(思想是高层复杂度才高,指数衰减,而复杂度增长是lg级别,因此被dominate掉了)
6.4 堆排序算法
堆排序算法:先建最大堆,每次把顶上的位置与合适的位置(合适的位置从后往前,因为最大值应该放在后面)互换,然后保持最大堆的性质, 共执行n次,其复杂度为 O(n lg n)
6.5 优先队列:集合的一个管理方式
假设有一个最大优先队列,支持的操作如下:
insert(x, S), max(S), extract_max(S), increase(x, k, S) - 将x的值增长为k,
最大优先队列的应用:计算机系统的作业调度,选取优先级最大的作业来做。
1、max 很显然。。。取第一个元素即可
2、extract_max 与之前堆排序中循环的操作相同,就是将最大的与最后一个对换,然后重新排出最大的,O(lg n),
3、insert操作:在最后加入,然后一点一点上移。
4、increase操作:原地增大,然后一点一点上移。
堆排序代码:
class MaxHeap(object): def __init__(self, initList): self.heap = initList[:] self.length = len(initList) self.heapLength = len(initList) self.construct() def leftChild(self, i): leftIndex = 2 * i + 1 return leftIndex if leftIndex < self.length else -1 def rightChild(self, i): rightIndex = 2 * i + 2 return rightIndex if rightIndex < self.length else -1 def keepMax(self, i): # print i, self.heap[i] while True: left = self.leftChild(i) right = self.rightChild(i) if left >= 0 and left < self.heapLength and self.heap[i] < self.heap[left]: if right >= 0 and right < self.heapLength and self.heap[left] < self.heap[right]: self.heap[i], self.heap[right] = self.heap[right], self.heap[i] i = right else: self.heap[i], self.heap[left] = self.heap[left], self.heap[i] i = left elif right >= 0 and right < self.heapLength and self.heap[i] < self.heap[right]: self.heap[i], self.heap[right] = self.heap[right], self.heap[i] i = right else: break # print self.heap[:self.heapLength] def construct(self): for i in reversed(range((self.heapLength + 1) / 2)): self.keepMax(i) def removeMax(self): self.heap[0], self.heap[self.heapLength - 1] = self.heap[self.heapLength - 1], self.heap[0] self.heapLength -= 1 return self def heapSort(xList): returnList = [] heap = MaxHeap(xList) for i in range(heap.length): max = heap.heap[0] heap.removeMax() heap.keepMax(0) returnList.append(max) return list(reversed(returnList)) if __name__ == '__main__': import random print heapSort([1, ]) print heapSort([2, 1]) print heapSort([2, 2, 1]) print heapSort([2, 3, 4, 1]) print heapSort([1, 2, 4, 3]) randomList = range(10) random.shuffle(randomList) print 'random:', randomList print heapSort(randomList)