【二叉树】基础理论:深度搜索和广度搜索(以递归写法为主)

一、深度搜索 dfs

  • 144.二叉树的前序遍历
  • 145.二叉树的后序遍历
  • 94.二叉树的中序遍历

144.二叉树的前序遍历

在这里插入图片描述

# 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 preorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
        res = []
        def dfs(root):
            if not root:
                return
            res.append(root.val)
            dfs(root.left)
            dfs(root.right)
        dfs(root)
        return res

145.二叉树的后序遍历

在这里插入图片描述

# 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 postorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
        res = []
        def dfs(root):
            if not root:
                return
            
            dfs(root.left)
            dfs(root.right)
            res.append(root.val)
        dfs(root)
        return res

94.二叉树的中序遍历

在这里插入图片描述

# 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 inorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
        res = []
        def dfs(root):
            if not root:
                return
            
            dfs(root.left)
            res.append(root.val)
            dfs(root.right)
            
        dfs(root)
        return res

前序、中序、后序的迭代(非递归)统一写法

# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right

# 前序
class Solution:
    def preorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
        res = []
        if not root:
            return []
        stack = [root]
        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:
    def preorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
        res = []
        if not root:
            return res
        stack = [root]
        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:
    def inorderTraversal(self, root: Optional[TreeNode]) -> 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

二、层序遍历 bfs

  • 102.二叉树的层序遍历
  • 107.二叉树的层次遍历II
  • 199.二叉树的右视图
  • 637.二叉树的层平均值
  • 429.N叉树的层序遍历
  • 515.在每个树行中找最大值
  • 116.填充每个节点的下一个右侧节点指针
  • 117.填充每个节点的下一个右侧节点指针II
  • 104.二叉树的最大深度
  • 111.二叉树的最小深度

102. 二叉树的层序遍历

在这里插入图片描述

# 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: Optional[TreeNode]) -> List[List[int]]:
        res = []

        def bfs(node,level,res):
            if not node:
                return
            if len(res) == level:
                res.append([])
            res[level].append(node.val)
            bfs(node.left,level+1,res)
            bfs(node.right,level+1,res)
        bfs(root,0, res)
        return res

107.二叉树的层次遍历 II

在这里插入图片描述

# 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: Optional[TreeNode]) -> List[List[int]]:
        res = []
        def bfs(node,level,res):
            if not node:
                return
            if len(res) == level:
                res.append([])
            res[level].append(node.val)
            bfs(node.left,level+1,res)
            bfs(node.right,level+1,res)
        bfs(root,0,res)
        return res[::-1]

199.二叉树的右视图

在这里插入图片描述

# 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: Optional[TreeNode]) -> List[int]:
        res_mid = []
        def bfs(node,level,res_mid):
            if not node:
                return
            if len(res_mid) == level:
                res_mid.append([])
            res_mid[level].append(node.val)
            bfs(node.left,level+1,res_mid)
            bfs(node.right,level+1,res_mid)
            
        bfs(root,0 ,res_mid)
        res = []
        for i in res_mid:
            res.append(i[-1])
        return res

637.二叉树的层平均值

在这里插入图片描述

# 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]:
        res_mid = []
        def bfs(node,level,res_mid):
            if not node:
                return
            if len(res_mid) == level:
                res_mid.append([])
            
            res_mid[level].append(node.val)
            bfs(node.left,level+1,res_mid)
            bfs(node.right,level+1,res_mid)
        bfs(root,0,res_mid)
        res = []
        for i in res_mid:
            res.append(mean(i))
        return res

429.N叉树的层序遍历

"""
# 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]]:
        res = []
        def bfs(node,level,res):
            if not node:
                return
            if len(res) == level:
                res.append([])
            res[level].append(node.val)
            for children in node.children:
                bfs(children,level+1,res)

        bfs(root,0,res)
        return res

515.在每个树行中找最大值

在这里插入图片描述

# 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]:
        res_mid = []
        def bfs(node,level,res_mid):
            if not node:
                return
            if len(res_mid) == level:
                res_mid.append([])
            res_mid[level].append(node.val)
            bfs(node.left,level+1,res_mid)
            bfs(node.right,level+1,res_mid)
        bfs(root,0,res_mid)
        res = []
        for i in range(len(res_mid)):
            res.append(max(res_mid[i]))
        return res

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: 'Optional[Node]') -> 'Optional[Node]':
        # if not root:
        #     return
        # if root.left:
        #     root.left.next = root.right
        #     if root.next:
        #         root.right.next = root.next.left
        # self.connect(root.left)
        # self.connect(root.right)
        # return root

        if not root:
            return
        def bfs(onelayer):  # onelayer为当前层的节点
            nextlayer = []
            for i in onelayer:
                if i.left:
                    nextlayer.append(i.left)
                if i.right:
                    nextlayer.append(i.right)
            if len(nextlayer)>1:
                for j in range(len(nextlayer)-1):
                    nextlayer[j].next = nextlayer[j+1]
            if nextlayer:  # nextlayer不为空的话继续往下走
                bfs(nextlayer)
        bfs([root])
        return root

117.填充每个节点的下一个右侧节点指针II

在这里插入图片描述

【核心思路】:整个题就是要把树拆成一层一层的,然后每层里面,前一个节点的next指向后一个节点。后面没有就是空的。
其实对于oneLayer这一层树的所有节点来说,把他们每个节点的左右取出来,就是下一层的节点了。

for i in oneLayer:
    if i.left:
        nextLayer.append(i.left)
    if i.right:
        nextLayer.append(i.right)

然后对nextLayer里所有节点,每个节点的next指向后一个节点就可以了。

"""
# 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
        def bfs(onelayer):
            nextlayer = []
            for i in onelayer:
                if i.left:
                    nextlayer.append(i.left)
                if i.right:
                    nextlayer.append(i.right)

            if len(nextlayer)>1:
                for j in range(len(nextlayer)-1):
                    nextlayer[j].next = nextlayer[j+1]
            if nextlayer:
                bfs(nextlayer)
        bfs([root])
        return root

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 maxDepth(self, root: Optional[TreeNode]) -> int:
        res_mid = []

        def bfs(node, level, res_mid):
            if not node:
                return
            if len(res_mid) == level:
                res_mid.append([])
            res_mid[level].append(node.val)
            bfs(node.left, level + 1, res_mid)
            bfs(node.right, level + 1, res_mid)

        bfs(root, 0, res_mid)
        
        return len(res_mid)

111.二叉树的最小深度

在这里插入图片描述
本题目主要注意一下两个图片里的东西即可。
在这里插入图片描述

在这里插入图片描述

# 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: Optional[TreeNode]) -> int:
        if not root:
            return 0
        if not root.left and not root.right:
            return 1
        leftdepth = self.minDepth(root.left)
        rightdepth = self.minDepth(root.right)
        if root.left and not root.right:  # 抛开右子数深度的问题
            return leftdepth+1
        if root.right and not root.left:  # 抛开左子树深度的问题
            return rightdepth+1
        min_depth = min(leftdepth,rightdepth)+1
        return min_depth

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
线索化二叉树是一种特殊的二叉树,它的每个节点都有一个指向前驱节点和后继节点的指针,这些指针称为线索。线索化二叉树可以提高遍历二叉树的效率。 中序线索化二叉树递归写法如下: ```python def in_order_threading(root): global pre pre = None def in_order_threading_recursive(node): global pre if not node: return in_order_threading_recursive(node.left) if not node.left: node.left = pre node.ltag = 1 if pre and not pre.right: pre.right = node pre.rtag = 1 pre = node in_order_threading_recursive(node.right) in_order_threading_recursive(root) ``` 其中,`node.ltag` 和 `node.rtag` 分别表示节点的左指针和右指针是否是线索,如果是线索,则为1,否则为0。 中序线索化二叉树的非递归写法可以使用栈来实现。具体步骤如下: 1. 从根节点开始,找到最左边的叶子节点,并将路径上所有节点入栈。 2. 当栈不为空时,弹出栈顶节点,并将其线索化。 3. 如果当前节点有右儿子,则将右儿子及其左子树中所有节点入栈,否则继续弹出栈顶节点。 代码实现如下: ```python def in_order_threading(root): pre = None stack = [] node = root while node or stack: while node: stack.append(node) node = node.left node = stack.pop() if not node.left: node.left = pre node.ltag = 1 if pre and not pre.right: pre.right = node pre.rtag = 1 pre = node node = node.right if not node.rtag else None ``` 需要注意的是,在非递归写法中,需要判断当前节点的右指针是否是线索,如果是线索,则直接将下一个节点设置为该线索指向的节点。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值