[Python] バイナリツリーのレベルトラバーサルとリスト表現


  バイナリ ツリーには、前順、中順、および後順のトラバーサルに加えて、 上から下、左から右のレベルのトラバーサル方法 もあります。このメソッドは人間の視覚的直観により近く、ツリーの最大深さの計算、最​​も外側のリーフ ノードの返し、バイナリ ツリーのリスト表現の返しなどのシナリオで優れたパフォーマンスを発揮します。
   リスト表現は、バイナリ ツリー グラフィック表現に加えて最も重要な表現方法であり 、階層トラバーサルを通じて実装できます。

1.バイナリツリーを作成する

バイナリ ツリーを構築するには、バイナリ ツリーの作成を参照してください。

class TreeNode:
    def __init__(self, val=0, left=None, right=None):
        self.val = val
        self.left = left
        self.right = right

node4 = TreeNode(1)
node5 = TreeNode(4)
node6 = TreeNode(6)
node7 = TreeNode(9)
node2 = TreeNode(3, node4, node5)
node3 = TreeNode(7, node6, node7)
node1 = TreeNode(5, node2, node3)
root = node1

二分木

2. レベルトラバーサル

2.1 コードの詳細説明

  • ルート ノードが空の場合は、空のリストが返されます。
  • Level と Next は、それぞれ現在のレベル ノードと次のレベル ノードを記録します。
  • Vals と Res は、それぞれ現在のレイヤーの値とすべてのレイヤーの値を記録します。ResはValsの蓄積です。
  • 現在のノード Level をループすると、現在のレイヤーの値 Vals と次のレイヤーのノード Next を取得できます。
  • Next が空の場合、トラバーサルは終了し、while ループは終了し、Res 2 次元配列が返されます。
def levelTraversal(root):
    if not root:
        return []
    Level = [root]   # 当前遍历层
    Res = []        # 层次遍历返回结果
    while True:
        Vals = []   # 当前层节点的值
        Next = []   # 下一层的节点
        for node in Level:
            Vals.append(node.val)
            if node.left is not None:   # 若存在左子节点,计入到下一层
                Next.append(node.left)
            if node.right is not None:  # 若存在右子节点,计入到下一层
                Next.append(node.right)
        Res.append(Vals)
        if len(Next) == 0:  # 如果下一层没有节点,说明遍历完成
            break
        else:
            Level = Next
    return Res

関数を実行し、2 次元のリスト式を返します。

>>> print(levelTraversal(root))
>>> [[5], [3, 7], [1, 4, 6, 9]]

2 次元のリスト式はトラバーサルに使用できますが、二分木を一方向にしか表現できず、二分木の構造を復元できないため、3 番目の部分では他の方法を使用する必要があります。

2.2 簡潔な文章

def levelTraversal(root):
    if not root:
        return []
    Level, Res = [root], []
    while Level:
        Vals, Next = [], []
        for node in Level:
            Vals.append(node.val)
            if node.left:
                Next.append(node.left)
            if node.right:
                Next.append(node.right)
        Res.append(Vals)
        Level = Next
    return Res

3. リスト表現

リスト式はバイナリ ツリーと 1 対 1 に対応しており、バイナリ ツリーの最も一般的な式の 1 つであり、この 2 つは相互に変換できます。

3.1 ルールの説明

上から下、左から右に移動する場合:

  • 親ノードに子ノードが 1 つしかない場合は、欠落している左右の子ノードの位置に「null」を使用します。
  • それが最後の層の葉ノードであり、左右の子ノードがない場合、子ノードはすべて「null」であるため、省略形は省略できます。

ここに画像の説明を挿入します
上に示すように:

  • 最初のレベルはルート ノードであるため、リスト式は次で始まります。[7]
  • 2 番目のレベルは完全なレベルであるため、このレベルのリスト式は次のようになります。[3,9]
  • 3 番目のレベルでは、9 の左右の子ノードは空で、「null」で埋められています。このレベルの式は次のようになります。[1,4,null,null]
  • 4 番目のレベルでは、1 の子ノードと 4 の左側の子ノードは空であり、"null" で埋められています。このレベルの式は次のようになります。[ヌル,ヌル,ヌル,5]
  • 5 番目のレベルでは、5 の左側の子ノードは空で、「null」で埋められています。このレベルの式は次のようになります。[null,6]
  • この時点で、最後のレイヤーに到達しており、これ以上の塗りつぶしは必要ありません。最終的な式は、上記のレイヤーを直接直列に接続することで取得できます。
    [7,3,9,1,4,null,null,null,null,null,5,null,6]

3.2 コードの実装

'''
class TreeNode:
    def __init__(self, val=0, left=None, right=None):
        self.val = val
        self.left = left
        self.right = right
        
node7 = TreeNode(6)
node6 = TreeNode(5, None, node7)
node5 = TreeNode(4, None, node6)
node4 = TreeNode(1)
node3 = TreeNode(9)
node2 = TreeNode(3, node4, node5)
node1 = TreeNode(7, node2, node3)
root = node1
'''
def listExpress(root):
    if not root:
        return []
    Level = [root]
    Expre = [root.val]
    while True:
        Next = []
        for node in Level:
            if node.left:
                Expre.append(node.left.val)
                Next.append(node.left)
            else:
                Expre.append("null")
            if node.right:
                Expre.append(node.right.val)
                Next.append(node.right)
            else:
                Expre.append("null")
        if not Next:
            return Expre[:len(Expre) - len(Level) * 2]
        Level = Next

関数呼び出し:

>>> print(listExpress(root))
>>> [7, 3, 9, 1, 4, 'null', 'null', 'null', 'null', 'null', 5, 'null', 6]

Supongo que te gusta

Origin blog.csdn.net/weixin_44844635/article/details/131641514
Recomendado
Clasificación