二叉树的遍历相关题目
再去动手实现二叉树的三种遍历,分别使用递归、迭代、颜色标记法
以深度优先搜索为原型的遍历
144二叉树的前序遍历
94二叉树的中序遍历
145二叉树的后序遍历
可能涉及:Morris 遍历方法
以广度优先搜索为原型的遍历,在树中称为层序遍历
LeetCode 中有三种:自顶向下层序、自底向上层序、锯齿层序遍历。
102二叉树的层次遍历
103二叉树的锯齿形层次遍历
107二叉树的层次遍历 ii
116填充每个节点的下一个右侧节点指针
117填充每个节点的下一个右侧节点指针 ii
144二叉树的前序遍历
解法一:迭代
解法二:递归
解法三:颜色标记法
其核心思想是使用颜色标记节点的状态
新节点为白色 已访问的节点为灰色:如果遇到的节点为白色,则将其标记为灰色,然后将其右子节点 、 左子节点 、 自身依次入栈 。
如果遇到的节点为灰色,则将节点的值输出 。
颜色标记法的优势:兼具栈迭代方法的高效,又像递归方法一样简洁易懂 更重要的是这种方法对于前序 、 中序 、 后序遍历 能够写出完全一致的代码 。
class Solution:
def preorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
if root == None:
return []
white,gray =0,1
stack = [(root,white)]
result = []
while stack:
node,color = stack.pop()
if node != None:
if color == white:
stack.append((node.right,white))
stack.append((node.left,white))
stack.append((node,gray))
else:
result.append(node.val)
return result
94二叉树的中序遍历
递归
class Solution:
def inorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
if root == None:
return []
result = [root.val]
left_val = self.inorderTraversal(root.left)
right_val = self.inorderTraversal(root.right)
return left_val + result + right_val
迭代
class Solution:
def inorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
if root == None:
return []
stack = []
output = []
p_node = root
while stack or p_node:
# 一直找到最左边的结点
while p_node:
stack.append(p_node)
p_node = p_node.left
# 弹出栈顶的结点
cur_node = stack.pop()
output.append(cur_node.val)
# 如果当前结点有右孩子,则指向右孩子,从而继续找左孩子
if cur_node.right:
p_node = cur_node.right
return output
颜色标记法
class Solution:
def inorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
if root == None:
return []
white,gray = 0,1
stack = [(white,root)]
output = []
while stack:
color ,node = stack.pop()
if node!= None:
if color == white:
stack.append((white,node.right))
stack.append((gray,node))
stack.append((white,node.left))
else:
output.append(node.val)
return output
145二叉树的后序遍历
class Solution:
def postorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
if root == None:
return []
result = []
result.append(root.val)
left_item = self.postorderTraversal(root.left)
right_item = self.postorderTraversal(root.right)
return left_item + right_item + result
class Solution:
def postorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
if root == None:
return []
stack = [root]
result = []
while stack:
node = stack.pop()
if node != None:
# 左右根 根右左
result.append(node.val)
stack.append(node.left)
stack.append(node.right)
return result[::-1]
class Solution:
def postorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
if root == None:
return []
white ,gray = 0,1
stack = [(white,root)]
result = []
while stack:
color,node = stack.pop()
if node!= None:
if color == white:
stack.append((gray,node))
stack.append((white,node.right))
stack.append((white,node.left))
else:
result.append(node.val)
return result
广度优先
102二叉树的层次遍历
迭代
class Solution:
def levelOrder(self, root: TreeNode) -> List[List[int]]:
if root == None:
return []
dequeue = [root]
result = []
while dequeue:
length = len(dequeue)
ceng = []
for _ in range(length):
node = dequeue.pop(0)
if node.left :
dequeue.append(node.left)
if node.right:
dequeue.append(node.right)
ceng.append(node.val)
result.append(ceng)
return result
递归
class Solution:
def levelOrder(self, root: TreeNode) -> List[List[int]]:
if root == None:
return []
res = []
def dfs(index,node):
if len(res) < index:
res.append([])
res[index-1].append(node.val)
if node.left:
dfs(index+1,node.left)
if node.right:
dfs(index+1,node.right)
dfs(1,root)
return res
103二叉树的锯齿形层次遍历
class Solution:
def zigzagLevelOrder(self, root: TreeNode) -> List[List[int]]:
if root == None:
return []
import collections
queue = collections.deque()
queue.append(root)
index = 1
res = []
while queue:
length = len(queue)
temp = []
for _ in range(length):
node = queue.popleft()
temp.append(node.val)
if node.left:
queue.append(node.left)
if node.right :
queue.append(node.right)
if (index&1)==1:
res.append(temp)
else:
res.append(temp[::-1])
index +=1
return res
class Solution:
def zigzagLevelOrder(self, root: TreeNode) -> List[List[int]]:
if root == None:
return []
res = []
import collections
def dfs(index,node):
if len(res) < index:
res.append(collections.deque())
if index%2:
res[index-1].append(node.val)
else:
res[index-1].appendleft(node.val)
if node.left:
dfs(index+1,node.left)
if node.right:
dfs(index+1,node.right)
dfs(1,root)
return [list(q) for q in res]
107二叉树的层次遍历 ii
class Solution:
def levelOrderBottom(self, root: TreeNode) -> List[List[int]]:
if root == None:
return []
queue= [root]
result = []
while queue:
length = len(queue)
temp= []
for _ in range(length):
node = queue.pop(0)
temp.append(node.val)
if node.left:
queue.append(node.left)
if node.right:
queue.append(node.right)
result.append(temp)
return result[::-1]
class Solution:
def levelOrderBottom(self, root: TreeNode) -> List[List[int]]:
if root == None:
return []
queue= [root]
import collections
result = collections.deque()
while queue:
length = len(queue)
temp= []
for _ in range(length):
node = queue.pop(0)
temp.append(node.val)
if node.left:
queue.append(node.left)
if node.right:
queue.append(node.right)
result.appendleft(temp)
return list(result)
class Solution:
def levelOrderBottom(self, root: TreeNode) -> List[List[int]]:
if root == None:
return []
res = []
def dfs(index,node):
if len(res)<index:
res.append([])
res[index-1].append(node.val)
if node.left:
dfs(index+1,node.left)
if node.right:
dfs(index+1,node.right)
dfs(1,root)
return res[::-1]
116填充每个节点的下一个右侧节点指针
class Solution:
def connect(self, root: 'Optional[Node]') -> 'Optional[Node]':
if not root:
return root
queue= [root]
res = []
while queue:
length = len(queue)
temp = queue[0]
for i in range(1,length):
temp.next = queue[i]
temp = queue[i]
for _ in range(length):
node = queue.pop(0)
if node.left:
queue.append(node.left)
if node.right:
queue.append(node.right)
return root
class Solution:
def connect(self, root: 'Optional[Node]') -> 'Optional[Node]':
if not root:
return root
pre = root
while pre.left:
temp = pre
while temp:
temp.left.next = temp.right
if temp.next:
temp.right.next = temp.next.left
temp = temp.next
pre = pre.left
return root
class Solution:
def connect(self, root: 'Optional[Node]') -> 'Optional[Node]':
def dfs(node):
if not node:
return node
left = node.left
right = node.right
while left:
left.next = right
left = left.right
right = right.left
dfs(node.left)
dfs(node.right)
dfs(root)
return root
117填充每个节点的下一个右侧节点指针 ii
class Solution:
def connect(self, root: 'Node') -> 'Node':
if root == None:
return root
queue = [root]
while queue:
length = len(queue)
temp = queue[0]
for i in range(1,length):
temp.next = queue[i]
temp = queue[i]
for _ in range(length):
temp = queue.pop(0)
if temp.left:
queue.append(temp.left)
if temp.right:
queue.append(temp.right)
return root
class Solution:
def connect(self, root: 'Node') -> 'Node':
if root == None:
return root
rootNode = root
oneNode_next = None
first_next = None
while rootNode:
if rootNode.left:
if not first_next:
first_next = rootNode.left
if oneNode_next :
oneNode_next.next = rootNode.left
oneNode_next = rootNode.left
if rootNode.right:
if not first_next :
first_next = rootNode.right
if oneNode_next:
oneNode_next.next = rootNode.right
oneNode_next = rootNode.right
rootNode = rootNode.next
if not rootNode:
rootNode = first_next
first_next = None
oneNode_next = None
return root