zoukankan      html  css  js  c++  java
  • 【算法导论】第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)
  • 相关阅读:
    java设计模式
    漏桶算法工具类
    http请求requestUtils
    去掉字符串中特殊符号造成的空格
    java 分布式id生成算法
    java枚举
    java 32个Java面试必考点
    配置tomcat下war包可以自压缩
    tomcat (选号)公司tomcat无页面解决
    docker 12 docker容器数据卷
  • 原文地址:https://www.cnblogs.com/yesuuu/p/7413888.html
Copyright © 2011-2022 走看看