1. 程式人生 > >Python實現大頂堆演算法

Python實現大頂堆演算法

# -*- coding: utf-8 -*-
class HeapTree(object):
    leftChild = None
    rightChild = None
    value = None
    # 排好順序的節點設定不可訪問
    visitable = True

    def __init__(self,value):
        self.value = value

    # 獲取當前節點頂部的 n 個子節點,先左後右
    def getTopNodeList(self,n):
        if n < 0:
            return
        p = self
        pointList = []
        left = True
        for i in xrange(n):
            if not isinstance(p,HeapTree):
                break
            print p.value
            pointList.append(p.leftChild)
            pointList.append(p.rightChild)
            p = pointList[0]
            pointList.remove(p)
    

    # 獲取最後一個節點
    def getLastNode(self):
        
        pointList = [self]
        index = 0

        while index < len(pointList):
            left = pointList[index].leftChild
            right = pointList[index].rightChild
            if left and left.visitable:
                pointList.append(left)
            if right and right.visitable:
                pointList.append(right)
            index += 1
        lastNode = pointList[-1]
        
        return lastNode
            


    # 展示結構
    def show(self):
        self._show(self,self.leftChild,"left")
        self._show(self,self.rightChild,"right")
        
        
    def _show(self,parent,child,desc=""):
        if isinstance(child,HeapTree):
            print "%s %s: %s" % (parent.value,desc,child.value) 
            child.show()


    # 堆排序
    def sort(self):

        self._sort()
        while True:
            lastNode = self.getLastNode()
            lastNode.visitable = False
            if lastNode == self:
                return
            self._swap(lastNode,self)


    # 獲得初始堆,排序邏輯
    def _sort(self):
        if  isinstance(self.leftChild,HeapTree):
            if not self.leftChild.visitable:
                return
            self.leftChild._sort()
            self._swap(self,self.leftChild)

        if isinstance(self.rightChild,HeapTree):
            if not self.rightChild.visitable:
                return
            self.rightChild._sort()
            self._swap(self,self.rightChild)



    # 交換父子節點的值
    def _swap(self,parent,child):
        if parent.value < child.value:
            temp = parent.value
            parent.value = child.value
            child.value = temp

            # 父子節點的值交換後,重新調整子節點結構
            child._sort()

            
        
class TreeManager(object):
    def __init__(self,data):
        self.data = data

    # 建立頂堆樹
    def bulidHeapTree(self):
        root = HeapTree(self.data[0])
        p = root
        pointList = []
        left = True
        for i in self.data[1:]:
            if left:
                p.leftChild = HeapTree(i)
                pointList.append(p.leftChild)
            else:
                p.rightChild = HeapTree(i)
                pointList.append(p.rightChild)
                p = pointList[0]
                pointList.remove(p)
            left = not left
        self.heapTree = root

    def show(self):
        self.heapTree.show()




if __name__ == '__main__':
    a = [2,3,4,1,5,6]
    m = TreeManager(a)
    m.bulidHeapTree()
    h = m.heapTree
    h.sort()
    h.show()
    h.getTopNodeList(8)