1. 程式人生 > >二叉樹(python實現)

二叉樹(python實現)

二叉樹是一種簡單的樹形結構,其每個節點的分支節點數有0,1或2個。如下圖T1,T2和T3是三棵二叉樹。顯然二叉樹是一種遞迴的結構。

 不包含任何節點的二叉樹為空樹,只有一個節點的二叉樹稱為單點樹,一個節點的子節點的個數稱為該節點的。如果每個分支節點的度都為2,則稱之為滿二叉樹。T4,T5就是兩棵滿二叉樹。

如果一棵二叉樹,除最後一層外,其它層的節點都是滿的,而最後一層節點在最左邊連續排列,空位都在右邊,這樣的二叉樹叫做完全二叉樹,如T6、T7所示。

以下程式碼定義了一個二叉樹類

想要遍歷一棵二叉樹,有兩種不同的策略:深度優先遍歷和寬度優先遍歷。

其中深度優先遍歷策略有三種不同的方式:

先根序遍歷:按根節點、左子樹、右子樹的順序遍歷。

中根序遍歷:按左子樹、根節點、右子樹的順序遍歷。

後根序遍歷:按左子樹、右子樹、根節點的順序遍歷。

#二叉樹節點類
class BinTNode:
    def __init__(self,dat,left=None,right=None):
        self.data=dat
        self.left=left
        self.right=right

class BinTree:
    def __init__(self):
        self._root=None

    def is_empty(self):
        return self._root is None

    def root(self):
        return self._root

    def leftchild(self):
        return self._root.left

    def rightchild(self):
        return self._root.right

    def set_root(self,rootnode):
        self._root=rootnode

    def set_left(self,leftchild):
        self._root.left=leftchild

    def set_right(self,rightchild):
        self._root.right=rightchild

    def preorder_elements(self):
        t=self._root
        s = SStack()
        while t is not None or not s.is_empty():
            while t is not None:
                yield t.data
                s.push(t.right)
                t = t.left
            t = s.pop()


其中 preorder_elements()函式可遍歷輸出二叉樹中的節點,實現了先根序遍歷的方法。

顯然二叉樹是是個遞迴結構,它的子樹仍然可看做一個二叉樹,因此二叉樹許多方法都可以用遞迴方式實現。如下程式碼所示:

#二叉樹節點類
class BinTNode:
    def __init__(self,dat,left=None,right=None):
        self.data=dat
        self.left=left
        self.right=right

#統計樹中節點的個數
def count_BinTNode(t):
    if t is None:
        return 0
    else:
        return 1+count_BinTNode(t.left)+count_BinTNode(t.right)

#求二叉樹裡的所有數值之和
def sum_BinTNode(t):
    if t is None:
        return 0
    else:
        return t.dat+sum_BinTNode(t.left)+sum_BinTNode(t.right)

#遞迴方式的深度遍歷二叉樹(先根序),proc是具體的節點資料操作
def preorder(t,proc):
    if t is None:
        return
    proc(t.data)
    preorder(t.left,proc)
    preorder(t.right,proc)

 此外可以藉助於佇列實現二叉樹的寬度優先遍歷

#寬度優先遍歷,proc是具體的節點資料操作
def levelorder(t,proc):
    qu=SQueue()
    qu.enqueue(t)
    while not qu.is_empty():
        n=qu.dequeue()
        if n is None:
            continue
        qu.enqueue(n.left)
        qu.enqueue(n.right)
        proc(n.data)