二叉樹的遍歷的實現 - python

1. 前言

在做二叉樹相關的算法題時,常常會遇到二叉樹的遍歷問題。而二叉樹的遍歷有4中方式,這4種方式都有其遞歸實現和迭代實現,本文僅記錄這4種遍歷方式的遞歸實現和迭代實現。

2. 深度優先遍歷(DFS)

DFS有三種,前序遍歷中序遍歷後序遍歷。這3種遍歷方式是基於根節點的先後而言的。
在這裏插入圖片描述

2.1 前序遍歷

根-左-右的順序遍歷二叉樹中的節點。遍歷順序爲:A-B-D-E-C-F-G

特點是,第一個節點爲二叉樹的根節點,子樹也滿足此規律。

  1. 根節點A加入棧中,棧爲 [A];
  2. 從棧中彈出節點A,將節點A的右子節點C和左子節點B依次入棧,此時棧爲 [C, B];
  3. 從棧中彈出節點B,將節點B的右子節點E和左子節點D依次入棧,此時棧爲 [C, E, D];
  4. 從棧中彈出節點D,沒有左子節點,此時棧爲 [C, E];
  5. 繼續上述步驟。
# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution:
	def pre_order(self, root):
		"""
		遞歸實現
		"""
		if not root: return
		print(root.val)
		self.pre_order(self, root.left)
		self.pre_order(self, root.right)
	
	 def pre_order(self, root):
	 	"""
	 	迭代實現,推薦使用
	 	"""
        if not root: return []
        result = [] 
        stack = [root]
        
        while stack:
            node = stack.pop()
            result.append(node.val)
            # 先加入右,再加左,因爲LIFO
            if node.right: stack.append(node.right)
            if node.left: stack.append(node.left)
            
        return result

2.2 中序遍歷

左-根-右的順序遍歷二叉樹中的節點。遍歷順序爲:D-B-E-A-F-C-G

特點是,根節點左邊的節點都在左子樹,根節點右邊的節點都在右子樹,子樹也滿足此規律。

  1. 有左就往左走,直到當前節點的最左子節點;
  2. 有右就往右走1步,再重複第1步,否則回溯到父節點,再重複第1步;
# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution:
	def in_order(self, root):
		"""
		遞歸實現
		"""
		if not root: return
		self.in_order(self, root.left)
		print(root.val)
		self.in_order(self, root.right)
		
	
    def in_order(self, root):
    	"""
    	迭代實現
    	"""
        result = []
        stack = []
        
        while root or stack:
        	# 1. 有左就往左走,直到最左子節點
            while root:
                stack.append(root)
                root = root.left
            # 2. 有右就往向右走1步,在重複第1步
            root = stack.pop()
            result.append(root.val)
            root = root.right
        
        return result

2.3 後序遍歷

左-右-根的順序遍歷二叉樹中的節點。遍歷順序爲:D-E-B-F-G-C-A

特點是,最後一個節點爲根節點,子樹也滿足此規律。

因爲先序遍歷的順序是 根-左-右, 後序遍歷的順序是 左-右-根。

採用先序遍歷的變形,首先實現一個根-右-左的遍歷,然後將其壓入輔助棧中,最後依次將輔助棧中的元素彈出即可。

例子中,根-右-左的遍歷順序爲:A-C-G-F-B-E-D

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution:
	def last_order(self, root):
		"""
		遞歸實現
		"""
		if not root: return
		self.last_order(self, root.left)
		self.last_order(self, root.right)
		print(root.val)

	def last_order(self, root):
		"""
		迭代實現
		"""
        if not root: return []
        result = []
        stack = [root]
        while stack:
            node = stack.pop()
            result.append(node.val)
            # 先入左,再入右
            if node.left: stack.append(node.left)
            if node.right: stack.append(node.right)
                
        result.reverse() # 逆序,將根-右-左變換爲左-右-根
        return result

3. 廣度優先遍歷(BFS)

廣度優先遍歷也就是我們常說的層序遍歷。遍歷順序爲:A-B-C-D-E-F-G

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution:
	def bfs(self, root):
		"""
		迭代實現版本1
        層序遍歷
        """
        if not root: return
        result = []
        queue = [root]
        
        while queue:
               node = queue.pop(0)
               result.append(node.val)
               if node.left: queue.append(node.left)
               if node.right: queue.append(node.right)
                
        return result

	def bfs(self, root):
		"""
		迭代實現版本2。這兩者的區別是,版本2能夠獲取具體每一層的數據,而版本1的混在一起的。
        層序遍歷
        """
        if not root: return
        result = []
        queue = [root]
        
        while queue:
            next_level = [] # 記錄下一層的節點
            while queue:
                node = queue.pop(0)
                result.append(node.val)
                if node.left: next_level.append(node.left)
                if node.right: next_level.append(node.right)
                
            queue = next_level
            
        return result
		

總結

本文僅是記錄二叉樹的實現,免得忘了之後又得在網上找半天。

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