概念:
トラバーサルの命名は
、アクセスノード操作が発生する場所に応じて名前が付けられます。
①NLR:プレオーダートラバーサル(プレオーダートラバーサルとも呼ばれます)
-ルートノードにアクセスする操作は、その左右のサブツリーをトラバースする前に発生します。
②LNR:インオーダートラバーサル
-ルートノードにアクセスする操作は、左右のサブツリーを(間で)トラバースするときに発生します。
③LRN:ポストオーダートラバーサル
-ルートノードにアクセスする操作は、その左右のサブツリーをトラバースした後に発生します。
共通の機能:3つのトラバーサル方法では、リーフノードの順序は左から右に同じです。
例えば:
注意:コードに従ってトラバーサルシーケンスを理解してから、この画像を自分でウォークスルーできます。
トラバーサルアルゴリズム:
1.1。プレオーダートラバーサル
一次(ルート、前)次数トラバーサルの再帰的アルゴリズムの定義:
二分木が空でない場合は、次の操作を順番に実行します。
(1)ルートノードにアクセスします。
(2)左側のサブツリーをトラバースします。
(3)右側のサブツリーをトラバースします。
Pythonコードのトラバーサルを事前注文します。
class Solution:
def preorderTraversal(self, root: TreeNode) -> List[int]:
def forward(root1):
if not root1:
return
ans.append(root1.val)
forward(root1.left)
forward(root1.right)
ans = []
forward(root)
return ans
2.2。順序どおりの走査
中(ルート)次数トラバーサルの再帰的アルゴリズムの定義:
二分木が空でない場合は、次の操作を順番に実行します。
(1)左側のサブツリーをトラバースします。
(2)ルートノードにアクセスします。
(3)右側のサブツリーをトラバースします。
Pythonコードをトラバースするには:
class Solution:
def inorderTraversal(self, root: TreeNode) -> List[int]:
def middle(root1):
if not root1:
return
middle(root1.left)
ans.append(root1.val)
middle(root1.right)
ans = []
middle(root)
return ans
3.3。注文後のトラバーサル
(ルート)オーダートラバーサル後の再帰的アルゴリズムの定義:
二分木が空でない場合は、次の操作を順番に実行します。
(1)左側のサブツリーをトラバースします。
(2)右側のサブツリーをトラバースします。
(3)ルートノードにアクセスします。
ポストオーダーでPythonコードをトラバースします。
class Solution:
def postorderTraversal(self, root: TreeNode) -> List[int]:
def backward(root1):
if not root1:
return
backward(root1.left)
backward(root1.right)
ans.append(root1.val)
ans = []
backward(root)
return ans
4.フロントトラバーサルシーケンスとミドルトラバーサルシーケンスを使用して、バイナリツリーを再構築します
アイデア:プレオーダートラバーサルの最初の要素はルートノードである必要があります。次に、ミドルオーダートラバーサルでミドルオーダールートノードの位置を見つけることにより、左右の葉の分布を判断できます(中次走査、ルートノードの左葉はすべて左葉、すべて右葉は後ろにあります)。
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def buildTree(self, preorder: List[int], inorder: List[int]) -> TreeNode:
if len(preorder)==0:
return
root = TreeNode(preorder[0]) # 根节点肯定是前序遍历的第一个
root_index = inorder.index(preorder[0]) # 返回中序遍历中根节点的位置,该位置之前全是左叶子,之后全是右叶子。注意前序和中序遍历序列中,左右叶子的长度肯定相同
root.left = self.buildTree(preorder[1:root_index+1], inorder[:root_index])
root.right = self.buildTree(preorder[root_index+1:], inorder[root_index+1:])
return root
5.中間およびポストトラバーサルシーケンスを使用してバイナリツリーを再構築します
アイデア:ポストオーダートラバーサルの最後の要素はルートノードである必要があります。次に、ミドルオーダートラバーサルでミドルオーダールートノードの位置を見つけることにより、左右の葉の分布を判断できます(中次走査、ルートノードの左葉はすべて左葉、すべて右葉は後ろにあります)。最後に、ポストオーダートラバーサルの分布は、ミドルオーダーの左右の葉の長さに従って判断されます(ポストオーダートラバーサルでは、すべての左の葉が左に分布し、すべての右の葉がすべてオンになります)権利)
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def buildTree(self, inorder: List[int], postorder: List[int]) -> TreeNode:
if not postorder:
return None
root = TreeNode(postorder[-1]) # 后序最后一个节点是根节点
n = inorder.index(root.val) # 取出中序中根节点的index,可以快速判别左右子树
root.left = self.buildTree(inorder[:n], postorder[:n]) # 在中序中,根节点的左子树元素都在左边;在后序中,根节点的右子树元素也都在左边
root.right = self.buildTree(inorder[n+1:], postorder[n:-1]) # 在中序中,根节点的右子树元素都在右边;在后序中,也都在左边,但是就不取最后一个元素了,因为最后一个是根
return root
注:前後の走査シーケンスを使用して一意の二分木を再構築することはできません。