二叉树理论、力扣94.二叉树的中序遍历、104.二叉树的最大深度、226.反转二叉树、101.对称二叉树

0.理论基础

参考:

二叉树理论基础篇 | 代码随想录

分类:

1、满二叉树:

如果一棵二叉树只有度为0的结点和度为2的结点,并且度为0的结点在同一层上,则这棵二叉树为满二叉树。

2、完全二叉树:

在完全二叉树中,除了最底层节点可能没填满外,其余每层节点数都达到最大值,并且最下面一层的节点都集中在该层最左边的若干位置。若最底层为第 h 层(h从1开始),则该层包含 1~ 2^(h-1) 个节点。

3、二叉搜索树:

有数值且有序

  • 若它的左子树不空,则左子树上所有节点的值均小于它的根节点的值;
  • 若它的右子树不空,则右子树上所有节点的值均大于它的根节点的值;
  • 它的左、右子树也分别为二叉排序树

4、平衡二叉搜索树:

又被称为AVL(Adelson-Velsky and Landis)树,且具有以下性质:它是一棵空树或它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一棵平衡二叉树。

遍历方式:

1、深度优先遍历:

先往深走,遇到叶子节点再往回走。

前中后序指中间节点的遍历顺序

  • 前序遍历------中左右(递归法,迭代法)
  • 中序遍历------左中右(递归法,迭代法)
  • 后序遍历------左右中(递归法,迭代法)

2、广度优先遍历:

逐层遍历

94.二叉树的中序遍历

一、递归

三部曲:

1、确定递归函数的参数和返回值:传入节点

2、确定终止条件:遍历节点为空直接返回

3、确定单层循环逻辑:中序遍历为左中右,按顺序循环,取中间节点数值

代码:

python 复制代码
class Solution:
    def inorderTraversal(self, root: Optional[TreeNode]) -> 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

二、迭代

思路:

用栈存储,需要时取出顶部元素。由于是中序遍历,首先迭代访问左子树,遍历到最左节点后取出栈顶元素加入结果数组,然后向栈顶元素的右子树进行遍历。

代码:

python 复制代码
class Solution:
    def inorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
        # 为空的情况
        if root is None:
            return []

        # 创建一个栈,先存储节点,便于回溯
        stack = []
        res = []
        cur = root

        # 需要两个
        while cur or stack:
            # 栈非空且当前节点非空
            if cur:
                # 向左遍历并存储(按中间、左节点的顺序存的,取出就为先取左节点再取的中间)
                stack.append(cur)
                cur = cur.left
            else: # 栈非空但当前节点为空
                # 取出左边/中间的节点存入结果数组,再向右遍历
                cur = stack.pop()
                res.append(cur.val)
                cur = cur.right

        return res

104.二叉树的最大深度

一、层序遍历

参考:

讲透二叉树的层序遍历 | 广度优先搜索 | LeetCode:102.二叉树的层序遍历_哔哩哔哩_bilibili

思路:

使用队列,用一个变量记录该层元素个数,以知道后续要从队列中弹出的元素个数;遍历每一层时需要将对应元素的子节点加入到队列当中

代码:

python 复制代码
class Solution:
    def maxDepth(self, root: Optional[TreeNode]) -> int:
        if root is None:
            return 0

        # 记录深度,创建列表
        depth = 0
        queue = collections.deque([root])

        while queue:
            depth += 1
            size = len(queue)  # 记录每一层的节点数

            # 按层来取出节点,加入下一层节点
            for _ in range(size):
                cur = queue.popleft()
                if cur.left:
                    queue.append(cur.left)
                if cur.right:
                    queue.append(cur.right)

        return depth

二、递归

三部曲:

1、确定参数及返回值:参数为节点,返回值为高度

2、确定终止条件:遍历节点为空返回0

3、确定单层循环逻辑:一定要是后序遍历左右中,因为只有把两个子树先遍历完了才能够对左子树和右子树高度进行比较,否则无法比较

代码:

python 复制代码
class Solution:
    def getDepth(self, node):
        if not node:
            return 0
        
        leftHeight = self.getDepth(node.left)
        rightHeight = self.getDepth(node.right)
        height = 1 + max(leftHeight, rightHeight)

        return height

    def maxDepth(self, root: Optional[TreeNode]) -> int:
        return self.getDepth(root)

226.反转二叉树

思路:

先交换左右节点,然后再递归处理左子树右子树

代码:

python 复制代码
class Solution:
    def invertTree(self, root: Optional[TreeNode]) -> Optional[TreeNode]:
        if root is None:
            return root

        root.left, root.right = root.right, root.left
        self.invertTree(root.left)
        self.invertTree(root.right)

        return root

复杂度分析:

  • 时间复杂度:O(n),其中 n 为二叉树的节点个数。
  • 空间复杂度:O(n)。最坏情况下,二叉树退化成一条链,递归需要 O(n) 的栈空间。

101.对称二叉树

一、递归

思路:

递归处理二叉树的外侧节点和内侧节点,分别对比对应节点是否相同;把特殊情况单列出来返回,包括:对应节点一个为空一个非空、都非空、值不相等的情况,此时可以直接返回,若两个值相等了,就可以继续递归

代码:

python 复制代码
class Solution:
    def compare(self, left, right):
        # 把左右节点的各种情况单独列出
        if left is None and right:
            return False
        elif right is None and left:
            return False
        elif right is None and left is None:
            return True
        elif left.val != right.val:
            return False

        # 分别遍历二叉树的外侧节点和内侧节点,来判断是否都相同
        outside = self.compare(left.left, right.right)
        inside = self.compare(left.right, right.left)
        isSame = outside and inside

        return isSame

    def isSymmetric(self, root: Optional[TreeNode]) -> bool:
        if root is None:
            return True

        return self.compare(root.left, root.right)

复杂度分析:

  • 时间复杂度:O(n),其中 n 为二叉树的节点个数。
  • 空间复杂度:O(n)。最坏情况下,二叉树退化成一条链,递归需要 O(n) 的栈空间。

二、迭代

思路:

和层序遍历有点像,用队列来成对记录左右节点,方便对比

代码:

python 复制代码
class Solution:
    def isSymmetric(self, root: Optional[TreeNode]) -> bool:
        if root is None:
            return True

        queue = collections.deque([root.left, root.right])  # 要传入左右节点

        while queue:
            leftNode = queue.popleft()
            rightNode = queue.popleft()

            # 两节点都为空
            if not leftNode and not rightNode:
                continue

            # 两节点有一个不为空或者值不相等
            if not leftNode or not rightNode or leftNode.val != rightNode.val:
                return False
            
            # 先传入外侧两节点,再传入内测两节点,方便两两对比
            queue.append(leftNode.left)
            queue.append(rightNode.right)
            queue.append(leftNode.right)
            queue.append(rightNode.left)

        return True
相关推荐
玄同7653 小时前
从 0 到 1:用 Python 开发 MCP 工具,让 AI 智能体拥有 “超能力”
开发语言·人工智能·python·agent·ai编程·mcp·trae
小瑞瑞acd4 小时前
【小瑞瑞精讲】卷积神经网络(CNN):从入门到精通,计算机如何“看”懂世界?
人工智能·python·深度学习·神经网络·机器学习
仟濹4 小时前
算法打卡day2 (2026-02-07 周五) | 算法: DFS | 3_卡码网99_计数孤岛_DFS
算法·深度优先
驭渊的小故事4 小时前
简单模板笔记
数据结构·笔记·算法
火车叼位4 小时前
也许你不需要创建.venv, 此规范使python脚本自备依赖
python
YuTaoShao4 小时前
【LeetCode 每日一题】1653. 使字符串平衡的最少删除次数——(解法一)前后缀分解
算法·leetcode·职场和发展
火车叼位4 小时前
脚本伪装:让 Python 与 Node.js 像原生 Shell 命令一样运行
运维·javascript·python
VT.馒头4 小时前
【力扣】2727. 判断对象是否为空
javascript·数据结构·算法·leetcode·职场和发展
goodluckyaa4 小时前
LCR 006. 两数之和 II - 输入有序数组
算法
孤狼warrior4 小时前
YOLO目标检测 一千字解析yolo最初的摸样 模型下载,数据集构建及模型训练代码
人工智能·python·深度学习·算法·yolo·目标检测·目标跟踪