【算法导论】第6章,堆排序

6.1 堆数据结构

是一个完全二叉树,从左向右填充。

有两个属性:树大小、有效数据长度。可以用数据表示,1 2 4 8 这种形式。

可以分为两种形式:最大堆和最小堆。最大堆:根节点不比叶子节点小。

最大堆:堆排序。最小堆:优先队列。

6.2 保持最大堆的性质

假设两个子堆都满足,只需要根节点依次换下去,复杂度O(lg n) 

6.3 初始化堆

后半段都是叶子,在前半段从后往前,依次执行上述最大堆性质的操作,名义复杂度是O(n lg n),但是有更精确的计算,

  在高度为h的节点为O(h), 因此为 nsigma (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)
原文地址:https://www.cnblogs.com/yesuuu/p/7413888.html