二叉樹的前序、中序、後序和層序遍歷的非遞歸實現

class Node(object):
    def __init__(self, data=-1, lchild=None, rchild=None):
        self.data = data
        self.lchild = lchild
        self.rchild = rchild
    
class Tree(object):
    def __init__(self):
        self.root = Node()
        self.treeQueue = []
        
    def add(self, data): # 層序添加成完全二叉樹
        node = Node(data) 
        if self.root.data == -1:  # 樹爲空
            self.root = node
            self.treeQueue.append(self.root)
        else:               # 樹不爲空,那麼隊列有根節點
            treeNode = self.treeQueue[0]   # 取隊列第一個數爲父結點
            if treeNode.lchild == None:   # 先加左子樹
                treeNode.lchild = node
                self.treeQueue.append(node)
            elif treeNode.rchild == None: # 後加右子樹
                treeNode.rchild = node
                self.treeQueue.append(node)
                self.treeQueue.pop(0)     # 父節點的左右子樹都賦值了
                
    def pre_order_recursion(self, root):  # 遞歸實現
        if not root:
            return 
        print(str(root.data) + " ", end='')
        self.pre_order_recursion(root.lchild)
        self.pre_order_recursion(root.rchild)
        
    def pre_order_stack(self, root):     # 堆棧:非遞歸實現
        if not root:
            return 
        stack = [] # pop() 函數用於移除列表中的一個元素(默認最後一個元素)
        node = root  # 初試化父節點
        while node or stack: # 一直有下一個節點,或者 stack裏面有元素
            while node:   # 從根結點開始一直尋找左子樹
                print(str(node.data) + " ", end='')
                stack.append(node) # 根
                node = node.lchild
            node = stack.pop()  # 當沒有下一個左子樹了,就返回最後一個父節點,看他的右子樹
            node = node.rchild
            
    def in_order_stack(self, root):       
        if not root:
            return
        stack = []
        node = root
        while node or stack:
            while node:
                stack.append(node)
                node = node.lchild
            # 當沒有左子樹了,就可以打印父節點了
            node = stack.pop()
            print(str(node.data) + " ", end='') # 中序和前序區別就在這一行
            node = node.rchild
            
    def post_order_stack(self, root):  
        # 後序遍歷難一些。利用先序:根->左-> 右, 變爲 根->右->左(左右有序)
        # 再輸出  左->右->根
        if not root:
            return
        stack = []
        post_stack = []
        node = root
        while stack or node:
            while node:
                stack.append(node)
                post_stack.append(node)
                node = node.rchild
            node = stack.pop()
            node = node.lchild
        while post_stack:
            print(str(post_stack.pop().data) + " ", end='')
    # 時間複雜度: O(n): 每個節點只遍歷一次
    # 空間複雜度: O(2N): 兩個stack
    
    def level_order_queue(self, root): # 隊列實現:父節點出列,他的左右子樹入列
        if not root:
            return
        queue = []
        node = root
        queue.append(node)
        while queue:
            node = queue.pop(0)
            print(str(node.data) + " ", end='')
            if node.lchild:
                queue.append(node.lchild)
            if node.rchild:
                queue.append(node.rchild)
        

if __name__ == '__main__':
    """主函數"""
    datas = [i for i in range(10)]        #生成十個數,放到樹中
    tree = Tree()   
    for data in datas:                  
        tree.add(data)           #逐個添加樹的節點
    print('遞歸實現前序遍歷:')
    tree.pre_order_recursion(tree.root)
    print("\n")
    tree.pre_order_stack(tree.root)
    print('\n非遞歸實現中序遍歷:')
    tree.in_order_stack(tree.root)
    print('\n非遞歸實現後序遍歷:')
    tree.post_order_stack(tree.root)
    print('\n隊列實現層次遍歷:')
    tree.level_order_queue(tree.root)

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章