インタビューの必要性:バイナリツリーのプレオーダー、ミドルオーダー、ポストオーダートラバーサル、およびPython実装コードと例を使用したフロントミドル、ミドルバックシーケンスを使用したバイナリツリーの再構築

概念:

トラバーサルの命名は
、アクセスノード操作が発生する場所に応じて名前が付けられます。

①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

注:前後の走査シーケンスを使用して一意の二分木を再構築することはできません。

おすすめ

転載: blog.csdn.net/weixin_44414948/article/details/114646712
おすすめ