学习笔记-二叉树-先序遍历-后序遍历的实现

二叉树类的的Python实现及其函数:包括统计结点个数,用递归实现的先序遍历,非递归实现的先序遍历,以及非递归实现的后序遍历。

class StackUnderflow(ValueError):   
    pass  
  
class SStack():  
    def __init__(self):  
        self.elems = []  
          
    def is_empty(self):  
        return self.elems == []  
      
    def top(self): #取得栈里最后压入的元素,但不删除  
        if self.elems == []:  
            raise StackUnderflow('in SStack.top()')  
        return self.elems[-1]  
      
    def push(self, elem):  
        self.elems.append(elem)  
          
    def pop(self):  
        if self.elems == []:  
            raise StackUnderflow('in SStack.pop()')  
        return self.elems.pop()
  
class BinTNode:
    def __init__(self, dat, left = None, right = None):
        self.data = dat
        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 proc(x):
    print(x, end = '')

#利用递归实现的先序遍历
def pre_order(t): 
    if t is None:
        return
    proc(t.data)
    pre_order(t.left)
    pre_order(t.right)
  
#利用非递归实现的先序遍历
def preorder_nonrec(t):
    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()       #遇到空树,回溯
    
#用带有括号的形式显示出树,^代表空
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 = '')
    
#用生成器实现非递归先序遍历;当需要遍历数据的时候,总应该想到迭代器
def preorder_elemnts(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()
    #非递归遍历算法的一个重要用途是作为实现迭代器的基础
        
#利用非递归实现的后序遍历
def postorder_elements(t):
    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

if __name__=="__main__":
    t = BinTNode(1, BinTNode(2, BinTNode(4), BinTNode(5)), BinTNode(3, BinTNode(6), BinTNode(7)))
    t = BinTNode(1, BinTNode(2,BinTNode(5)), BinTNode(3))
    print(count_BinTNodes(t))
    print(sum_BinTNodes(t))
    preorder_nonrec(t)
    print(pre_order(t))
    print_BinTNodes(t)
    for i in preorder_elements(t):
        print(i)
    postorder_elements(t)

猜你喜欢

转载自blog.csdn.net/qq_34840129/article/details/80643670