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