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