1. 程式人生 > >17_資料結構與演算法_二叉堆_Python實現

17_資料結構與演算法_二叉堆_Python實現

#Created By: Chen Da

#先實現一個二叉堆,基於完整二叉樹
class Binary_heap(object):
    def __init__(self):
        self.heap_list = [0]            #一個空的二叉堆以零作為第一個元素,方便後續的整除計算
        self.curr_size = 0

    #通過比較新新增的項與父項的大小,如果該項小於父項則交換,從而維持堆的結構屬性
    def swap_up(self,i):
        while i // 2 > 0:
            if self.heap_list[i] < self.heap_list[i // 2]:
                tmp = self.heap_list[i]
                self.heap_list[i] = self.heap_list[i//2]
                self.heap_list[i//2] = tmp
            i //= 2

    def insert(self,i):
        self.heap_list.append(i)
        self.curr_size += 1
        self.swap_up(self.curr_size)

    #尋找當前節點的最小子節點
    def find_min_child(self,i):
        if i * 2 + 1 > self.curr_size:
            return i * 2
        else:
            if self.heap_list[i * 2] < self.heap_list[i * 2 + 1]:
                return i * 2
            return i * 2 + 1

    #交換節點與其子節點直到都滿足正確的位置
    def swap_down(self,i):
        while (i * 2) <= self.curr_size:
            min_child = self.find_min_child(i)
            if self.heap_list[i] > self.heap_list[min_child]:
                tmp = self.heap_list[i]
                self.heap_list[i] = self.heap_list[min_child]
                self.heap_list[min_child] = tmp
            i  = min_child

    def del_min(self):
        min_value = self.heap_list[1]
        #將最後一項交換到首項
        self.heap_list[1] = self.heap_list[self.curr_size]
        self.curr_size -= 1
        self.heap_list.pop()
        #維持堆正確的結構屬性
        self.swap_down(1)
        return min_value

    #利用列表構建堆的方法
    def build_heap(self,lyst):
        i = len(lyst) // 2      #從樹的中間開始
        self.curr_size = len(lyst)
        self.heap_list = [0] + lyst[:]
        while i > 0:
            self.swap_down(i)
            i -= 1

    def get_list(self):
        return self.heap_list

def test_binary_heap():
    bh = Binary_heap()
    bh.build_heap([3,5,7,1,2,9,4,11,17])
    print(bh.get_list())
    assert bh.del_min() == 1
    print(bh.get_list())
    bh.insert(15)
    print(bh.get_list())



if __name__ == "__main__":
    test_binary_heap()