二叉树理论基础
链接:https://programmercarl.com/%E4%BA%8C%E5%8F%89%E6%A0%91%E7%90%86%E8%AE%BA%E5%9F%BA%E7%A1%80.html
种类
- 满二叉树:满二叉树:如果一棵二叉树只有度为0的结点和度为2的结点,并且度为0的结点在同一层上,则这棵二叉树为满二叉树。
- 完全二叉树:在完全二叉树中,除了最底层节点可能没填满外,其余每层节点数都达到最大值,并且最下面一层的节点都集中在该层最左边的若干位置。
- 二叉搜索树:有序数,左孩子<根节点<右孩子
- 平衡二叉搜索树/AVL(Adelson-Velsky and Landis)树:它是一棵空树或它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一棵平衡二叉树。
遍历方式
- 深度优先遍历
前序遍历:中左右
在每个节点前面画点,先碰到点的数字先输出
中序遍历:左中右
在每个节点底下画点,先碰到点的数字先输出
后序遍历:左右中
在每个节点后面画点,先碰到点的数字先输出
2. 广度优先遍历
层序遍历:一层一层输出
5, 4, 6, 1, 2, 7, 8
定义
class TreeNode:
def __init__(self, val, left = None, right = None):
self.val = val
self.left = left
self.right = right
二叉树的递归遍历
LeetCode 144. 二叉树的前序遍历
# Definition for a binary tree node.
# class TreeNode(object):
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution(object):
def preorderTraversal(self, root):
"""
:type root: TreeNode
:rtype: List[int]
"""
res = []
def dfs(root):
if root:
res.append(root.val)
dfs(root.left)
dfs(root.right)
dfs(root)
return res
LeetCode 94. 二叉树的中序遍历
# Definition for a binary tree node.
# class TreeNode(object):
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution(object):
def inorderTraversal(self, root):
"""
:type root: TreeNode
:rtype: List[int]
"""
res = []
def dfs(root):
if root:
dfs(root.left)
res.append(root.val)
dfs(root.right)
dfs(root)
return res
LeetCode 145. 二叉树的后序遍历
# Definition for a binary tree node.
# class TreeNode(object):
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution(object):
def postorderTraversal(self, root):
"""
:type root: TreeNode
:rtype: List[int]
"""
res = []
def dfs(root):
if root:
dfs(root.left)
dfs(root.right)
res.append(root.val)
dfs(root)
return res
二叉树的迭代遍历
使用栈结构:深度遍历需要先按一个方向遍历到底,其他方向的信息暂时压入栈,之后再取出。
不可以用队列:不满足其他方向信息暂存,因为先压入的信息一定会先出。
LeetCode 144. 二叉树的前序遍历
前序遍历:中左右
把右孩子压入栈 -> 左孩子压入栈(这样可以先出左孩子,再出右孩子) -> 出栈记录val
# Definition for a binary tree node.
# class TreeNode(object):
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
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
LeetCode 94. 二叉树的中序遍历
中序遍历:左中右
【比较难】
把自己和左孩子压入栈 -> 直到没有左孩子,开始pop,并压入右孩子
# Definition for a binary tree node.
# class TreeNode(object):
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution(object):
def inorderTraversal(self, root):
"""
:type root: TreeNode
:rtype: List[int]
"""
if not root:
return
stack = []
res = []
node = root
while stack or node:
while node:
stack.append(node)
node = node.left
node = stack.pop()
res.append(node.val)
node = node.right
return res
LeetCode 145. 二叉树的后序遍历
[1,2,4,6,5] -> [1,2,4,6,5] -> [5,6,4,2,1]
前序遍历先压入左孩子,后压入右孩子 -> res[::-1]
# Definition for a binary tree node.
# class TreeNode(object):
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
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]
二叉树的统一迭代遍历
在压入自己时加入标记符null,遇到null则直接输出自己
LeetCode 144. 二叉树的前序遍历
前序遍历:中左右
压入顺序:右左中
# Definition for a binary tree node.
# class TreeNode(object):
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
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()
if not node:
node = stack.pop()
res.append(node.val)
elif node.left or node.right:
if node.right:
stack.append(node.right)
if node.left:
stack.append(node.left)
stack.append(node)
stack.append(None)
else:
res.append(node.val)
return res
LeetCode 94. 二叉树的中序遍历
中序遍历:左中右
压入顺序:右中左
# Definition for a binary tree node.
# class TreeNode(object):
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution(object):
def inorderTraversal(self, root):
"""
:type root: TreeNode
:rtype: List[int]
"""
if not root:
return
stack = [root]
res = []
while stack:
node = stack.pop()
if not node:
node = stack.pop()
res.append(node.val)
elif node.left or node.right:
if node.right:
stack.append(node.right)
stack.append(node)
stack.append(None)
if node.left:
stack.append(node.left)
else:
res.append(node.val)
return res
LeetCode 145. 二叉树的后序遍历
后序遍历:左右中
压入顺序:中右左
# Definition for a binary tree node.
# class TreeNode(object):
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
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()
if not node:
node = stack.pop()
res.append(node.val)
elif node.left or node.right:
stack.append(node)
stack.append(None)
if node.right:
stack.append(node.right)
if node.left:
stack.append(node.left)
else:
res.append(node.val)
return res
二叉树的层序遍历
LeetCode 102. 二叉树的层序遍历
用队列结构保存信息。
利用队列长度区分不同层:
# Definition for a binary tree node.
# class TreeNode(object):
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution(object):
def levelOrder(self, root):
"""
:type root: TreeNode
:rtype: List[List[int]]
"""
if not root:
return
queue = collections.deque()
queue.append(root)
res = []
while queue:
level = []
for _ 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
迭代法,核心就是按顺序扩充每层:
def traverse(node, level):
res[level].append(node.val)
traverse(node.left, level + 1)
traverse(node.right, level + 1)
再加上一些辅助条件,保证程序顺利运行:
# Definition for a binary tree node.
# class TreeNode(object):
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution(object):
def levelOrder(self, root):
"""
:type root: TreeNode
:rtype: List[List[int]]
"""
if not root:
return
res = []
def traverse(node, level):
if not node:
return
if len(res) == level:
res.append([])
res[level].append(node.val)
traverse(node.left, level + 1)
traverse(node.right, level + 1)
traverse(root, 0)
return res
LeetCode 107. 二叉树的层序遍历 II
把res反转即可
# Definition for a binary tree node.
# class TreeNode(object):
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution(object):
def levelOrderBottom(self, root):
"""
:type root: TreeNode
:rtype: List[List[int]]
"""
if not root:
return
queue = collections.deque()
queue.append(root)
res = []
while queue:
level = []
for _ 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]
LeetCode 199. 二叉树的右视图
只保留每层的最后一个数
# Definition for a binary tree node.
# class TreeNode(object):
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution(object):
def rightSideView(self, root):
"""
:type root: TreeNode
:rtype: List[int]
"""
if not root:
return
queue = collections.deque()
queue.append(root)
right_view = []
while queue:
queue_len = len(queue)
for i in range(queue_len):
node = queue.popleft()
if i == queue_len-1:
right_view.append(node.val)
if node.left:
queue.append(node.left)
if node.right:
queue.append(node.right)
return right_view
LeetCode 637. 二叉树的层平均值
每层求平均,注意level要写成0.0,默认float
# Definition for a binary tree node.
# class TreeNode(object):
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution(object):
def averageOfLevels(self, root):
"""
:type root: TreeNode
:rtype: List[float]
"""
if not root:
return
queue = collections.deque()
queue.append(root)
res = []
while queue:
level = 0.0
queue_len = len(queue)
for _ in range(queue_len):
node = queue.popleft()
level += node.val
if node.left:
queue.append(node.left)
if node.right:
queue.append(node.right)
res.append(level/queue_len)
return res
LeetCode 429. N 叉树的层序遍历
把孩子依次存入队列
"""
# Definition for a Node.
class Node(object):
def __init__(self, val=None, children=None):
self.val = val
self.children = children
"""
class Solution(object):
def levelOrder(self, root):
"""
:type root: Node
:rtype: List[List[int]]
"""
if not root:
return
queue = collections.deque()
queue.append(root)
res = []
while queue:
level = []
for _ in range(len(queue)):
node = queue.popleft()
level.append(node.val)
for children in node.children:
queue.append(children)
res.append(level)
return res
LeetCode 515. 在每个树行中找最大值
# Definition for a binary tree node.
# class TreeNode(object):
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution(object):
def largestValues(self, root):
"""
:type root: TreeNode
:rtype: List[int]
"""
if not root:
return
queue = collections.deque()
queue.append(root)
res = []
while queue:
max_num = float('-inf')
for _ in range(len(queue)):
node = queue.popleft()
max_num = max(max_num, node.val)
if node.left:
queue.append(node.left)
if node.right:
queue.append(node.right)
res.append(max_num)
return res
LeetCode 116. 填充每个节点的下一个右侧节点指针
"""
# Definition for a Node.
class Node(object):
def __init__(self, val=0, left=None, right=None, next=None):
self.val = val
self.left = left
self.right = right
self.next = next
"""
class Solution(object):
def connect(self, root):
"""
:type root: Node
:rtype: Node
"""
if not root:
return
queue = collections.deque()
queue.append(root)
while queue:
cur = None
queue_len = len(queue)
for i in range(queue_len):
node = queue.popleft()
if cur:
cur.next = node
cur = node
if node.left:
queue.append(node.left)
if node.right:
queue.append(node.right)
return root
LeetCode 117. 填充每个节点的下一个右侧节点指针 II
"""
# Definition for a Node.
class Node(object):
def __init__(self, val=0, left=None, right=None, next=None):
self.val = val
self.left = left
self.right = right
self.next = next
"""
class Solution(object):
def connect(self, root):
"""
:type root: Node
:rtype: Node
"""
if not root:
return
queue = collections.deque()
queue.append(root)
while queue:
cur = None
queue_len = len(queue)
for i in range(queue_len):
node = queue.popleft()
if cur:
cur.next = node
cur = node
if node.left:
queue.append(node.left)
if node.right:
queue.append(node.right)
return root
LeetCode 104. 二叉树的最大深度
# Definition for a binary tree node.
# class TreeNode(object):
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution(object):
def maxDepth(self, root):
"""
:type root: TreeNode
:rtype: int
"""
if not root:
return 0
queue = collections.deque()
queue.append(root)
depth = 0
while queue:
for _ in range(len(queue)):
node = queue.popleft()
if node.left:
queue.append(node.left)
if node.right:
queue.append(node.right)
depth += 1
return depth
LeetCode 111. 二叉树的最小深度
当左右孩子都为空时,说明遍历到最低点了
# Definition for a binary tree node.
# class TreeNode(object):
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution(object):
def minDepth(self, root):
"""
:type root: TreeNode
:rtype: int
"""
if not root:
return 0
queue = collections.deque()
queue.append(root)
depth = 0
while queue:
depth += 1
for _ in range(len(queue)):
node = queue.popleft()
if not node.left and not node.right:
return depth
if node.left:
queue.append(node.left)
if node.right:
queue.append(node.right)
return depth