二分木プレオーダー、ミッドオーダー、ポストオーダー、シーケンストラバーサル(再帰、反復、スタック、キュー)
1.二分木のトラバーサルのプレオーダー
1.1トピックの説明
難易度:中程度
1.2問題分析
この問題は、二分木に関連する問題の基本的な問題です。再帰の使用は比較的簡単に考えることができますが、高度な問題の場合は、反復アルゴリズムを実行する必要があります。ただし、バイナリツリーの前順、中次、および後順のトラバーサルに関して、適用できる統一されたテンプレートがあります。このテンプレートが何であるかを見てみましょう。
"""
二叉树遍历模板
采用栈的方法
"""
stack = []
cur = root
while stack or cur:
if cur:
pass
else:
pass
バイナリツリーの前順、中次、および後順トラバーサルは、上記のスタックテンプレートを使用して実装でき、状況に応じてコードのパスセグメントを変更するだけで済みます。二分木の前順走査の順序は、ルートノード->左サブツリー->右サブツリーです。二分木の前順走査がどのように実装されているか見てみましょう。
1.3 Pythonの実装
- 再帰
最初に、再帰的方法を使用して以下を実現します。
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def preorderTraversal(self, root: TreeNode) -> List[int]:
if not root:
return []
return [root.val] + self.preorderTraversal(root.left) + self.preorderTraversal(root.right)
実行結果は次のとおりです。
- 反復(スタック)
では、上記のテンプレートを使用して以下を実現します。
class Solution(object):
def preorderTraversal(self, root):
"""
:type root: TreeNode
:rtype: List[int]
"""
stack = []
res = []
cur = root
while stack or cur:
if cur:
stack.append(cur)
res.append(cur.val)
cur = cur.left
else:
cur = stack.pop()
cur = cur.right
return res
実行結果は次のとおりです。
2.二分木の中位トラバーサル
2.1トピックの説明
難易度:中程度
2.2問題分析
中間順序のトラバーサルは、前の順序のトラバーサルに似ています。トラバーサルの順序は、左サブツリー->ルートノード->右サブツリーです。再帰と反復を実装するには2つの方法があります。反復は、セクション1.2のテンプレートを使用して実現されます。
2.3 Pythonの実装
- 再帰的な実装
class Solution:
def inorderTraversal(self, root: TreeNode) -> List[int]:
if not root:
return []
return self.inorderTraversal(root.left) + [root.val] + self.inorderTraversal(root.right)
出力は次のとおりです。
- 反復実装(スタック)
class Solution:
def inorderTraversal(self, root: TreeNode) -> List[int]:
stack = []
res = []
cur = root
while stack or cur:
if cur:
stack.append(cur)
cur = cur.left
else:
cur = stack.pop()
res.append(cur.val)
cur = cur.right
return res
出力は次のとおりです。
3.二分木の後順走査
2.1トピックの説明
難易度:難しい
2.2問題分析
後順シーケンスは>ルートノード- >右サブツリー-左サブツリーテンプレート1.2を使用して、反復の二種類を達成するためにトラバース、同様の反復と再帰的INORDER、プリアンブルシーケンスプレオーダー達成しました。
2.3 Pythonの実装
- 再帰的な実装
class Solution:
def postorderTraversal(self, root: TreeNode) -> List[int]:
if not root:
return []
return self.postorderTraversal(root.left) + self.postorderTraversal(root.right) + [root.val]
実行結果は次のとおりです。
- 反復実装(スタック)
class Solution:
def postorderTraversal(self, root: TreeNode) -> List[int]:
stack = []
res = []
cur = root
temp = None
while stack or cur:
if cur:
stack.append(cur)
cur = cur.left
else:
cur = stack[-1]
if(cur.right is None or cur.right == temp):
res.append(cur.val)
temp = cur
stack.pop()
cur = None
else:
cur = cur.right
return res
実行結果は次のとおりです。
4.バイナリツリーのシーケンストラバーサル
2.1トピックの説明
難易度:中程度
2.2問題分析
シーケンス走査の走査順序は、次のとおりです。最初のレイヤー:ルートノード、2番目のレイヤー:左ノード、右ノード、3番目のレイヤー...出力は2次元のリストです。最初の3つの質問とは異なり、シーケンストラバーサルはスタック構造では実現できず、キューで実現できます。手順は次のとおりです。
- ルートノードをキューに入れます
- キュー内のノードを取得し、その値を出力に追加して、ノードの左と右の子をキューに入れます
- キューの長さをサイクル数として、キューの列の最初の値を順番に取り、ノードの値を出力結果に追加し、ノードの左と右の子ノードを同時にキューに入れます
- キューが空になるまで3番目の手順を繰り返します
2.3 Pythonの実装
コードは次のとおりです。
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
# 队列
class Solution:
def levelOrder(self, root: TreeNode) -> List[List[int]]:
if not root:
return []
res = []
queue = [root]
temp = []
while queue:
lens = len(queue)
temp = []
while lens:
cur = queue[0]
del queue[0]
temp.append(cur.val)
if cur.left:
queue.append(cur.left)
if cur.right:
queue.append(cur.right)
lens -= 1
res.append(temp)
return res
出力は次のとおりです。