Go语言实战案例-判断二叉树是否对称

给定一棵二叉树,判断这棵树是否是对称的。对称的含义是:这棵树的左子树和右子树在结构上是镜像对称的,且对应节点的值相等。

示例 1:

arduino 复制代码
    1
   / \
  2   2
 / \ / \
3  4 4  3

输出:true

示例 2:

arduino 复制代码
    1
   / \
  2   2
   \   \
   3    3

输出:false

二、应用场景

  • • 用户界面或布局中验证左右对称性
  • • 算法竞赛题目或笔试面试常考
  • • 树结构可视化或分析工具中,对称性判断用于简化处理

三、解题思路

本问题的关键在于:比较树的左子树和右子树是否镜像对称

我们可以采用两种方法:

方法一:递归判断

判断左右子树是否满足以下三个条件:

    1. 左子树的左子树和右子树的右子树对称;
    1. 左子树的右子树和右子树的左子树对称;
    1. 当前两个节点值相同。

方法二:迭代判断(借助队列)

使用队列存储成对的节点,每次成对弹出并比较:

  • • 若都为空,继续;
  • • 若一个为空另一个不为空 → 不对称;
  • • 值不相等 → 不对称;
  • • 否则将子节点成对压入队列,继续判断。

四、Go语言实现

1. 数据结构定义

go 复制代码
package main

import "fmt"

type TreeNode struct {
    Val   int
    Left  *TreeNode
    Right *TreeNode
}

2. 方法一:递归法

go 复制代码
func isSymmetric(root *TreeNode) bool {
    if root == nil {
        return true
    }
    return isMirror(root.Left, root.Right)
}

func isMirror(left, right *TreeNode) bool {
    if left == nil && right == nil {
        return true
    }
    if left == nil || right == nil {
        return false
    }
    if left.Val != right.Val {
        return false
    }
    return isMirror(left.Left, right.Right) && isMirror(left.Right, right.Left)
}

3. 方法二:迭代法(使用队列)

go 复制代码
func isSymmetricIterative(root *TreeNode) bool {
    if root == nil {
        return true
    }

    queue := []*TreeNode{root.Left, root.Right}

    for len(queue) > 0 {
        left := queue[0]
        right := queue[1]
        queue = queue[2:]

        if left == nil && right == nil {
            continue
        }
        if left == nil || right == nil || left.Val != right.Val {
            return false
        }

        queue = append(queue, left.Left, right.Right)
        queue = append(queue, left.Right, right.Left)
    }

    return true
}

五、测试样例

ini 复制代码
func main() {
    // 构建对称二叉树
    root := &TreeNode{Val: 1}
    root.Left = &TreeNode{Val: 2}
    root.Right = &TreeNode{Val: 2}
    root.Left.Left = &TreeNode{Val: 3}
    root.Left.Right = &TreeNode{Val: 4}
    root.Right.Left = &TreeNode{Val: 4}
    root.Right.Right = &TreeNode{Val: 3}

    fmt.Println("递归判断结果:", isSymmetric(root))           // true
    fmt.Println("迭代判断结果:", isSymmetricIterative(root)) // true
}

六、复杂度分析

方式 时间复杂度 空间复杂度
递归法 O(n) O(h)
迭代法 O(n) O(n)
  • • n 表示节点数量;
  • • h 表示树的高度(递归调用栈的深度);
  • • 迭代方法使用了队列,需要额外 O(n) 空间存储节点。

七、可视化理解

将二叉树从中心线对折,看左、右两部分是否完全重合,节点值是否相等。

镜像对称结构满足:

  • left.Left == right.Right
  • left.Right == right.Left

八、变种与扩展

    1. 判断 N 叉树是否镜像对称:需要成对比较左右子节点;
    1. 输出是否对称的最小修改操作:可结合动态规划思想;
    1. 判断对称层级:例如仅判断前两层是否对称。

九、总结

内容 说明
核心判断条件 左右子树是否镜像结构,对应节点值是否相等
递归 vs 迭代 递归写法更直观,迭代适合大树或避免栈溢出
技巧点 左-右子树配对判断,使用队列模拟递归过程
实用价值 面试高频,掌握树结构对称性判断通用技巧

相关推荐
appearappear33 分钟前
Mac 上重新安装了Cursor 2.2.30,重新配置 springboot 过程记录
java·spring boot·后端
谷哥的小弟1 小时前
Spring Framework源码解析——RequestContext
java·后端·spring·框架·源码
IT_陈寒1 小时前
Vite 5大优化技巧:让你的构建速度飙升50%,开发者都在偷偷用!
前端·人工智能·后端
鹿角片ljp2 小时前
Spring Boot Web入门:从零开始构建web程序
前端·spring boot·后端
程序员阿鹏2 小时前
SpringBoot自动装配原理
java·开发语言·spring boot·后端·spring·tomcat·maven
程序员爱钓鱼2 小时前
Node.js 编程实战:CSV&JSON &Excel 数据处理
前端·后端·node.js
老华带你飞2 小时前
工会管理|基于springboot 工会管理系统(源码+数据库+文档)
java·数据库·vue.js·spring boot·后端·spring
Echo flower2 小时前
Spring Boot WebFlux 实现流式数据传输与断点续传
java·spring boot·后端
Way2top2 小时前
Go语言动手写Web框架 - Gee第二天 上下文Context
go
小徐Chao努力2 小时前
Go语言核心知识点底层原理教程【变量、类型与常量】
开发语言·后端·golang