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()