打卡Day13
- 1.理论基础
- 2.二叉树的递归遍历
- 3.二叉树的迭代遍历
- 3.二叉树的统一迭代法
- 4.102.二叉树的层序遍历
- 扩展
- 107. 二叉树的层序遍历 II
- 199.二叉树的右视图
- 637.二叉树的层平均值
- 429.N叉树的层序遍历
- 515.在每个树行中找最大值
- 116.填充每个节点的下一个右侧节点指针
- 117. 填充每个节点的下一个右侧节点指针 II
- 104. 二叉树的最大深度
- #111.二叉树的最小深度
1.理论基础
文档讲解: 代码随想录
解题过程二叉树有两种主要形式:满二叉树和完全二叉树。
(1)满二叉树:一棵二叉树只有度为0的节点和度为2的节点,并且度为0的节点在同一层上。深度为 k 的满二叉树有 2^k - 1 个节点。
(2)完全二叉树:除了最底层节点可能没填满外,其余每层节点数都达到最大值,并且最下面的节点都集中在该层最左边的若干位置。若最底层为第 h(h >= 1) 层,则该层包含 1 ~ 2^(h -1) 。
之前优先级队列其实是一个堆,堆是一颗完全二叉树,同时保证父子节点的顺序关系。
二叉搜索树:是一个有序树。
平衡二叉搜索树:是一棵空树或它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一棵平衡二叉树。
二叉树的定义:
class TreeNode:
def __init__(self, val, left = None, right = None):
self.val = val
self.left = left
self.right = right
2.二叉树的递归遍历
文档讲解: 代码随想录
递归算法的三要素:
(1)确定递归函数的参数和返回值:确定哪些参数是递归的过程中需要处理的,那么就在递归函数里加上这个参数,并且还要明确每次递归的返回值是什么进而确定递归函数的返回类型。
(2)确定终止条件:如果递归没有终止,操作系统的内存站必然会溢出。运行递归算法遇到栈溢出的错误,就是没写终止条件或者终止条件写的不对。
(3)确定单层递归的逻辑:确定每一层递归需要处理的信息,在这里也就会重复调用自己来实现递归的过程。
以前序遍历为例:
(1)确定递归函数的参数和返回值:参数为当前树节点,返回值为空。我本来以为需要返回节点的数据,但在函数的内部直接将数据加入到列表中。
(2)终止条件:当遍历的节点为空,直接return。
(3)确定单层递归的逻辑:先取中节点的数值,再取左节点,最后右节点。
题目链接:前序遍历
class Solution(object):
def preorderTraversal(self, root):
"""
:type root: TreeNode
:rtype: List[int]
"""
res = []
def dfs(node):
if node is None:
return
res.append(node.val)
dfs(node.left)
dfs(node.right)
dfs(root)
return res
题目链接:后序遍历
class Solution(object):
def postorderTraversal(self, root):
"""
:type root: TreeNode
:rtype: List[int]
"""
res = []
def dfs(node):
if node is None:
return
dfs(node.left)
dfs(node.right)
res.append(node.val)
dfs(root)
return res
题目链接:中序遍历
class Solution(object):
def inorderTraversal(self, root):
"""
:type root: TreeNode
:rtype: List[int]
"""
res = []
def dfs(node):
if node is None:
return
dfs(node.left)
res.append(node.val)
dfs(node.right)
dfs(root)
return res
3.二叉树的迭代遍历
文档讲解: 代码随想录
题目链接:前序遍历
class Solution(object):
def preorderTraversal(self, root):
"""
:type root: TreeNode
:rtype: List[int]
"""
if not root:
return []
#跟节点先入栈
stack = [root]
res = []
while stack:
node = stack.pop()
#处理中节点
res.append(node.val)
#右孩子先入栈
if node.right:
stack.append(node.right)
#左孩子入栈
if node.left:
stack.append(node.left)
return res
题目链接:后序遍历
class Solution(object):
def postorderTraversal(self, root):
"""
:type root: TreeNode
:rtype: List[int]
"""
if not root:
return []
stack = [root]
res = []
while stack:
node = stack.pop()
res.append(node.val)
if node.left:
stack.append(node.left)
if node.right:
stack.append(node.right)
return res[::-1]
题目链接:中序遍历
在中序遍历中,处理元素和访问元素的顺序不一致,需要借助指针的遍历来帮助访问节点,栈用来处理节点上的元素。不能提前将根节点放入栈中,如果先放入的话,迭代处理会先访问跟节点,而不是最左边的叶子节点。
class Solution(object):
def inorderTraversal(self, root):
"""
:type root: TreeNode
:rtype: List[int]
"""
if not root:
return []
res = []
stack = []
cur = root
while cur or stack:
#先迭代访问最左边的叶子节点
if cur:
stack.append(cur)
cur = cur.left
else:
#此时cur = null
cur = stack.pop()
res.append(cur.val)
cur = cur.right
return res
3.二叉树的统一迭代法
文档讲解: 代码随想录
题目链接:前序遍历
class Solution(object):
def preorderTraversal(self, root):
"""
:type root: TreeNode
:rtype: List[int]
"""
res = []
stack = []
if root:
stack.append(root)
while stack:
node = stack.pop()
if node != None:
if node.right:
stack.append(node.right)
if node.left:
stack.append(node.left)
stack.append(node)
stack.append(None)
else:
node = stack.pop()
res.append(node.val)
return res
题目链接:后序遍历
class Solution(object):
def postorderTraversal(self, root):
"""
:type root: TreeNode
:rtype: List[int]
"""
res = []
stack = []
if root:
stack.append(root)
while stack:
node = stack.pop()
if node != None:
stack.append(node)
stack.append(None)
if node.left:
stack.append(node.left)
if node.right:
stack.append(node.right)
else:
node = stack.pop()
res.append(node.val)
return res
题目链接:中序遍历
class Solution(object):
def inorderTraversal(self, root):
"""
:type root: TreeNode
:rtype: List[int]
"""
res = []
stack = []
if root:
stack.append(root)
while stack:
node = stack.pop()
if node != None:
if node.right:
stack.append(node.right)
stack.append(node)
stack.append(None)
if node.left:
stack.append(node.left)
else:
node = stack.pop()
res.append(node.val)
return res
4.102.二叉树的层序遍历
题目链接:102.二叉树的层序遍历
文档讲解: 代码随想录
class Solution(object):
def levelOrder(self, root):
"""
:type root: TreeNode
:rtype: List[List[int]]
"""
if not root:
return []
queue = collections.deque([root])
res = []
while queue:
level = []
for i in range(len(queue)):
cur = queue.popleft()
level.append(cur.val)
if cur.left:
queue.append(cur.left)
if cur.right:
queue.append(cur.right)
res.append(level)
return res
递归法:
class Solution(object):
def levelOrder(self, root):
"""
:type root: TreeNode
:rtype: List[List[int]]
"""
if not root:
return []
levels = []
def traverse(node, level):
if not node:
return
if len(levels) == level:
levels.append([])
levels[level].append(node.val)
traverse(node.left, level + 1)
traverse(node.right, level + 1)
traverse(root, 0)
return levels
扩展
107. 二叉树的层序遍历 II
题目链接:107
思路:在上题的基础上,输出的时候反转一下顺序。
class Solution(object):
def levelOrderBottom(self, root):
"""
:type root: TreeNode
:rtype: List[List[int]]
"""
if not root:
return []
res = []
queue = collections.deque([root])
while queue:
level = []
for i in range(len(queue)):
node = queue.popleft()
level.append(node.val)
if node.left:
queue.append(node.left)
if node.right:
queue.append(node.right)
res.append(level)
return res[::-1]
199.二叉树的右视图
题目链接:199
一开始题目没有理解好,以为是将每层元素从右往左组成列表输出。题目要求的是只输出每层最右边元素组成的一维列表。
class Solution(object):
def rightSideView(self, root):
"""
:type root: TreeNode
:rtype: List[int]
"""
if not root:
return []
res = []
queue = collections.deque([root])
while queue:
#需要用变量存储长度,因为下面会对队列进行操作
size = len(queue)
for i in range(size):
node = queue.popleft()
if i == size - 1:
res.append(node.val)
if node.left:
queue.append(node.left)
if node.right:
queue.append(node.right)
return res
637.二叉树的层平均值
题目链接:637
class Solution(object):
def averageOfLevels(self, root):
"""
:type root: TreeNode
:rtype: List[float]
"""
if not root:
return []
queue = collections.deque([root])
res = []
while queue:
summ = 0
size = len(queue)
for i in range(size):
node = queue.popleft()
summ += node.val
if node.left:
queue.append(node.left)
if node.right:
queue.append(node.right)
res.append(round(summ / size, 4))
return res
出现的问题:
将自己的代码替换到python3中是可行的,感觉是数据类型有点问题,具体是什么问题不能确认,暂时没有解决。
429.N叉树的层序遍历
题目链接:429
class Solution(object):
def levelOrder(self, root):
"""
:type root: Node
:rtype: List[List[int]]
"""
if not root:
return []
res = []
queue = collections.deque([root])
while queue:
level = []
size = len(queue)
for i in range(size):
node = queue.popleft()
level.append(node.val)
#用for循环遍历孩子节点
for child in node.children:
queue.append(child)
res.append(level)
return res
515.在每个树行中找最大值
题目链接:515
class Solution(object):
def largestValues(self, root):
"""
:type root: TreeNode
:rtype: List[int]
"""
if not root:
return []
queue = collections.deque([root])
res = []
while queue:
size = len(queue)
maxx = queue[0].val#可以使用maxx = float('-inf')初始化
for i in range(size):
node = queue.popleft()
if node.val > maxx:
maxx = node.val
if node.left:
queue.append(node.left)
if node.right:
queue.append(node.right)
res.append(maxx)
return res
116.填充每个节点的下一个右侧节点指针
题目链接:116
class Solution(object):
def connect(self, root):
"""
:type root: Node
:rtype: Node
"""
if not root:
return root
queue = collections.deque([root])
while queue:
size = len(queue)
pre = None
for i in range(size):
node = queue.popleft()
if pre:
pre.next = node
pre = node
if node.left:
queue.append(node.left)
if node.right:
queue.append(node.right)
return root
117. 填充每个节点的下一个右侧节点指针 II
题目链接:117
class Solution(object):
def connect(self, root):
"""
:type root: Node
:rtype: Node
"""
if not root:
return root
queue = collections.deque([root])
while queue:
size = len(queue)
pre = None
for i in range(size):
node = queue.popleft()
if pre:
pre.next = node
pre = node
if node.left:
queue.append(node.left)
if node.right:
queue.append(node.right)
return root
104. 二叉树的最大深度
题目链接:104
class Solution(object):
def maxDepth(self, root):
"""
:type root: TreeNode
:rtype: int
"""
if not root:
return 0
queue = collections.deque([root])
deep = 0
while queue:
size = len(queue)
deep += 1
for i in range(size):
node = queue.popleft()
if node.left:
queue.append(node.left)
if node.right:
queue.append(node.right)
return deep
#111.二叉树的最小深度
题目链接:111
class Solution(object):
def minDepth(self, root):
"""
:type root: TreeNode
:rtype: int
"""
if not root:
return 0
deep = 0
queue = collections.deque([root])
while queue:
size = len(queue)
deep += 1
for i in range(size):
node = queue.popleft()
if not node.left and not node.right:
return deep
if node.left:
queue.append(node.left)
if node.right:
queue.append(node.right)
return deep