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