二叉樹的先序遍歷、中序遍歷、后續遍歷(采用遞歸和棧兩種)層序遍歷(使用隊列)


首先我們要先自己建立一個二叉樹,我們先根據我自己隨便寫的二叉樹建立一個列表保存二叉樹的各個節點的信息,當然你也可以直接寫個程序自己建立。

node_list = [
    {'data':'A', 'left':'B', 'right':'C', 'is_root':True},
    {'data':'B', 'left':'D', 'right':'E', 'is_root':False},
    {'data':'C', 'left':'F', 'right':'G', 'is_root':False},
    {'data':'D', 'left':None, 'right':None, 'is_root':False},
    {'data':'E', 'left':'H', 'right':None, 'is_root':False},
    {'data':'H', 'left':None, 'right':None, 'is_root':False},
    {'data':'F', 'left':None, 'right':None, 'is_root':False},
    {'data':'G', 'left':'I', 'right':'J', 'is_root':False},
    {'data':'I', 'left':None, 'right':None, 'is_root':False},
    {'data':'J', 'left':None, 'right':None, 'is_root':False}
]

然后根據建的列表建立一個二叉樹

 1 from collections import deque
 2 class BinTreeNode(object):
 3     def __init__(self, data, left=None, right=None):
 4         self.data, self.left, self.right = data, left, right
 5 
 6 class BinTree(object):
 7     
 8     def __init__(self, root=None):
 9         self.root = root
10     
11     @classmethod
12     def build_form(cls, node_list):
13         node_dict = {}
14         for node_data in node_list:
15 #這一步是把所有節點存在node_dict中
16             data = node_data['data']
17             node_dict[data] = BinTreeNode(data)
18 '''這一步是根據存在node_dict中的節點字典,把對應的左右節點對應上'''
19         for node_data in node_list:
20             data = node_data['data']
21             if node_data['is_root']:
22                 root = node_dict[data]
23             node_dict[data].left = node_dict.get(node_data['left'])
24             node_dict[data].right = node_dict.get(node_data['right'])
25         return cls(root)

接下來是幾種遍歷

先序遍歷:即先遍歷根節點然后遍歷左節點接着是右節點

第一種:采用遞歸

['A', 'B', 'D', 'E', 'H', 'C', 'F', 'G', 'I', 'J']
def prevorder_trav(self, subtree):
        if subtree:
            yield subtree
            yield from self.prevorder_trav(subtree.left)
            yield from self.prevorder_trav(subtree.right)

我個人比較傾向於返回對應節點而不是直接返回值,這樣我們還可以對二叉樹的每個節點操作。當然你也可以直接返回subtree.date

第二種:采用棧

棧FILO因此我們要先把右節點入棧再把左節點入棧

 1 def prevorder_trav_stack(self, subtree):
 2         s = deque()
 3         s.append(subtree)
 4         while s:
 5             node = s.pop()
 6             yield node
 7             if node.right:
 8                 s.append(node.right)
 9             if node.left:
10                 s.append(node.left)

中序遍歷:先遍歷左節點再遍歷根節點最后遍歷右節點,這個先遍歷左節點是要遍歷最左,左到它下一個左節點為None

第一種:使用遞歸

['D', 'B', 'H', 'E', 'A', 'F', 'C', 'I', 'G', 'J']
def inorder_trav(self, subtree):
        if subtree:
            yield from self.inorder_trav(subtree.left)
            yield subtree
            yield from self.inorder_trav(subtree.right)

第二種使用棧:

 

def inorder_trav_use_stack(self, subtree):
        s = deque()
        top = subtree
        while s or top:
            while top:
                s.append(top)
                top = top.left
                
            top = s.pop()
            print(top.data)
            top = top.right

 

后序遍歷

遞歸

def postorder_trav(self, subtree):
        if subtree:
            yield from self.postorder_trav(subtree.left)
            yield from self.postorder_trav(subtree.right)
            yield subtree.data

使用棧:

def postorder_trav_use_stack(self, subtree):
        p = subtree
        s = deque()
        s.append(p)
        s.append(p)
        while s:
            p = s.pop()
            if s and p == s[-1]:
                if p.right:
                    s.append(p.right)
                    s.append(p.right)
                if p.left:
                    s.append(p.left)
                    s.append(p.left)
            else:
                yield p.data

 層序遍歷:

def layer_trav(self, subtree):
        if subtree:
            s = deque()
            s.append(subtree)
            while s:
                node = s.popleft()
                yield node.data
                if node.left:
                    s.append(node.left)
                if node.right:
                    s.append(node.right)

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM