07_05.經過連接實現二叉樹及其遍歷

from queue.queue import SQueue
from sstack.stack import SStack


class BinTNode:
    def __init__(self, data, left=None, right=None):
        self.data = data
        self.left = left
        self.right = right


def count_BinTNodes(t):
    """統計樹中結點個數"""
    if t is None:
        return 0
    else:
        return 1 + count_BinTNodes(t.left) + count_BinTNodes(t.right)


def sum_BinTNodes(t):
    """全部數值和(二叉樹保存的是數值)"""
    if t is None:
        return 0
    else:
        return t.data + sum_BinTNodes(t.left) + sum_BinTNodes(t.right)

遍歷:

先根序遍歷遞歸:

def preorder(t, proc):
    """先根序遍歷"""
    if t is None:
        return
    assert (isinstance(t, BinTNode))
    proc(t.data)
    preorder(t.left, proc)
    preorder(t.right, proc)


tree = BinTNode(1, BinTNode(2, BinTNode(4), BinTNode(5)), BinTNode(3, BinTNode(6), BinTNode(7)))
preorder(tree, lambda x: print(x, end=' '))  # 1 2 4 5 3 6 7
print()


def print_BinTNodes(t):
    """先根序遍歷打印"""
    if t is None:
        print("^", end="")
        return
    print("(" + str(t.data), end="")
    print_BinTNodes(t.left)
    print_BinTNodes(t.right)
    print(")", end="")


t = BinTNode(1, BinTNode(2, BinTNode(4), BinTNode(5)), BinTNode(3, BinTNode(6), BinTNode(7)))
print_BinTNodes(t)  # (1(2(4^^)(5^^))(3(6^^)(7^^)))
print()

先根序遍歷非遞歸:

def preorder_nonrec(t, proc):
    """非遞歸的先根遍歷--用棧"""
    s = SStack()
    while t is not None or not s.is_empty():
        while t is not None:
            proc(t.data)  # 先處理根
            s.push(t.right)  # 右分支入棧
            t = t.left  # 沿左分支下行
        t = s.pop()  # 遇到空樹回溯


tree = BinTNode(1, BinTNode(2, BinTNode(4), BinTNode(5)), BinTNode(3, BinTNode(6), BinTNode(7)))
preorder_nonrec(tree, lambda x: print(x, end=' '))  # 1 2 4 5 3 6 7
print("")

先根序遍歷非遞歸優化:

def preorder_elements(t):
    """非遞歸的先根遍歷優化,使用生成器"""
    s = SStack()
    while t is not None or not s.is_empty():
        while t is not None:
            s.push(t.right)  # 右分支入棧
            yield t.data
            t = t.left  # 沿左分支下行
        t = s.pop()  # 遇到空樹回溯


tree = BinTNode(1, BinTNode(2, BinTNode(4), BinTNode(5)), BinTNode(3, BinTNode(6), BinTNode(7)))
for i in preorder_elements(tree):
    print(i, end=' ')  # 1 2 4 5 3 6 7

 

寬度優先遍歷:

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)


tree = BinTNode(1, BinTNode(2, BinTNode(4), BinTNode(5)), BinTNode(3, BinTNode(6), BinTNode(7)))
levelorder(tree, lambda x: print(x, end=' '))  # 1 2 3 4 5 6 7
print("")

非遞歸實現後根序遍歷:

def postorder_nonrec(t, proc):
    """非遞歸實現後根序遍歷"""
    s = SStack()
    while t is not None or not s.is_empty():
        while t is not None:  # 下行循環,直到棧頂的兩子樹空
            s.push(t)
            t = t.left if t.left is not None else t.right
        t = s.pop()  # 棧頂是訪問結點
        proc(t.data)
        if not s.is_empty() and s.top().left == t:  # 棧不爲空且訪問結點是棧頂的左子結點
            t = s.top().right
        else:  # 沒有右子樹或右子樹遍歷完畢,進行退棧
            t = None


tree = BinTNode(1, BinTNode(2, BinTNode(4), BinTNode(5)), BinTNode(3, BinTNode(6), BinTNode(7)))
postorder_nonrec(tree, lambda x: print(x, end=' '))  # 4 5 2 6 7 3 1
print()

 將二叉樹封裝成類:

"""二叉樹類"""
from sstack.stack import SStack


class BinTNode:
    """結點"""
    def __init__(self, data, left=None, right=None):
        self.data = data
        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, s = self._root, SStack()
        while t is not None or not s.is_empty():
            while t is not None:
                s.push(t.right)
                yield t.data
                t = t.left
            t = s.pop()


l = BinTNode(2, BinTNode(4), BinTNode(5))
r = BinTNode(3, BinTNode(6), BinTNode(7))
tree = BinTree()
tree.set_root(BinTNode(1))
tree.set_left(l)
tree.set_right(r)
for i in tree.preorder_elements():
    print(i, end=' ')  # 1 2 4 5 3 6 7
print()
相關文章
相關標籤/搜索