二叉树的层序遍历,就是图论中的广度优先搜索
在二叉树中的应用,需要借助队列
来实现(此时又发现队列的一个应用了)。
# 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 levelOrder(self, root: TreeNode) -> List[List[int]]:
result = []
if not root:
return result
que = deque([root])
while que:
#获取每层的长度
size = len(que)
r = []
for _ in range(size):
#头结点出队 添加值
cur =que.popleft()
r.append(cur.val)
# 左右孩子添加到队列
if cur.left:
que.append(cur.left)
if cur.right:
que.append(cur.right)
result.append(r)
return result
# 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 levelOrderBottom(self, root: TreeNode) -> List[List[int]]:
result = []
if not root:
return result
que =deque([root])
while que:
size = len(que)
r = []
for _ in range(size):
cur =que.popleft()
r.append(cur.val)
if cur.left:
que.append(cur.left)
if cur.right:
que.append(cur.right)
result.append(r)
return result[::-1]
层序遍历的时候,判断是否遍历到单层的最后面的元素,如果是,就放进result数组中,随后返回result就可以了。
# 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 rightSideView(self, root: TreeNode) -> List[int]:
r = []
if not root:
return r
que = deque([root])
while que:
size = len(que)
for i in range(size):
cur = que.popleft()
# 说明是本层的最后一个元素 加入
if i == size-1:
r.append(cur.val)
if cur.left:
que.append(cur.left)
if cur.right:
que.append(cur.right)
return r
# 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 averageOfLevels(self, root: Optional[TreeNode]) -> List[float]:
r = []
if not root:
return r
que = deque([root])
while que:
# 要先记下que的长度 否则移动过程长度会变化
size = len(que)
sum = 0
ave = 0
for _ in range(size):
cur = que.popleft()
sum += cur.val
if cur.left:
que.append(cur.left)
if cur.right:
que.append(cur.right)
ave = sum/size
r.append(ave)
return r
"""
# Definition for a Node.
class Node:
def __init__(self, val=None, children=None):
self.val = val
self.children = children
"""
class Solution:
def levelOrder(self, root: 'Node') -> List[List[int]]:
result = []
if not root:
return result
que = deque([root])
while que:
r = []
size = len(que)
for _ in range(size):
cur = que.popleft()
r.append(cur.val)
# 像二叉树模板一样 队列中添加孩子结点
if cur.children:
que.extend(cur.children)
result.append(r)
return result
# 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 largestValues(self, root: Optional[TreeNode]) -> List[int]:
result = []
if not root:
return result
que = deque([root])
while que:
r = []
size = len(que)
for _ in range(size):
cur = que.popleft()
r.append(cur.val)
if cur.left:
que.append(cur.left)
if cur.right:
que.append(cur.right)
result.append(max(r))
return result
本题依然是层序遍历,只不过在单层遍历的时候记录一下本层的头部节点,然后在遍历的时候让前一个节点指向本节点就可以了。
总结:让当前结点(已经pop出来了)的next指向下一个结点,即队列里的第0个
"""
# Definition for a Node.
class Node:
def __init__(self, val: int = 0, left: 'Node' = None, right: 'Node' = None, next: 'Node' = None):
self.val = val
self.left = left
self.right = right
self.next = next
"""
class Solution:
def connect(self, root: 'Optional[Node]') -> 'Optional[Node]':
if not root:
return root
que = deque([root])
while que:
r = []
size = len(que)
for i in range(size):
cur = que.popleft()
if cur.left:
que.append(cur.left)
if cur.right:a
que.append(cur.right)
# 已经到最后一个结点 next已经默认设置成None
if i == size-1:
break
# 当前结点(已经pop出来了)的next指向他的下一个结点(队列的第0元素)
cur.next = que[0]
return root
思路:
这道题目说是二叉树,但116题目说是完整二叉树,其实没有任何差别,一样的代码一样的逻辑一样的味道
"""
# Definition for a Node.
class Node:
def __init__(self, val: int = 0, left: 'Node' = None, right: 'Node' = None, next: 'Node' = None):
self.val = val
self.left = left
self.right = right
self.next = next
"""
class Solution:
def connect(self, root: 'Node') -> 'Node':
if not root:
return root
que = deque([root])
while que:
r = []
size = len(que)
for i in range(size):
cur = que.popleft()
if cur.left:
que.append(cur.left)
if cur.right:
que.append(cur.right)
# 已经到最后一个结点 next已经默认设置成None
if i == size-1:
break
# 当前结点(已经pop出来了)的next指向他的下一个结点(队列的第0元素)
cur.next = que[0]
return root
# 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 maxDepth(self, root: Optional[TreeNode]) -> int:
if not root:
return 0
que = deque([root])
k = 0 # 记录遍历的层数
while que:
r = []
size = len(que)
for i in range(size):
cur = que.popleft()
if cur.left:
que.append(cur.left)
if cur.right:
que.append(cur.right)
k+=1
return k
相对于 104.二叉树的最大深度 ,本题还也可以使用层序遍历的方式来解决,思路是一样的。
需要注意的是,只有当左右孩子都为空
的时候,才说明遍历的最低点了。如果其中一个孩子为空则不是最低点
# 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 minDepth(self, root: TreeNode) -> int:
if not root:
return 0
que = deque([root])
k = 0 # 记录层数
while que:
size = len(que)
k += 1 # 开始进入新的一层
for i in range(size):
cur = que.popleft()
if cur.left:
que.append(cur.left)
if cur.right:
que.append(cur.right)
# 左右孩子都空 则返回k
if cur.left == None and cur.right == None:
return k
return 0
# 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 minDepth(self, root: TreeNode) -> int:
if not root:
return 0
# 根节点深度1
que = deque([(root,1)])
while que:
size = len(que)
for i in range(size):
cur,k = que.popleft()
# 假设是根节点 左右孩子都空 则返回k
if cur.left == None and cur.right == None:
return k
# 因为在一个for循环内 有左还右孩子 层数都加1
if cur.left:
que.append((cur.left,k+1))
if cur.right:
que.append((cur.right,k+1))
return 0
# 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 zigzagLevelOrder(self, root: TreeNode) -> List[List[int]]:
if not root:
return []
res = []
que = deque([root])
k = 0
while que:
r = []
size = len(que)
for i in range(size):
cur = que.popleft()
r.append(cur.val)
if cur.left:
que.append(cur.left)
if cur.right:
que.append(cur.right)
k += 1
if k % 2 == 0:
r = r[::-1]
res.append(r)
return res