news 2026/6/9 22:45:48

二叉树的相关知识以及代码实现(Java)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
二叉树的相关知识以及代码实现(Java)

一、二叉树的定义与基本概念

二叉树是一种非线性数据结构,每个节点最多包含 2 个子节点(左子节点、右子节点),核心特点:

(1)每个节点的子树数量不超过 2;

(2)左、右子树是有序的(即使只有一个子树,也需明确是左 / 右子树);

(3)可衍生出多种特殊结构(如二叉搜索树、完全二叉树、满二叉树等)。

二、创建二叉树的常见方法

1. 节点类定义

二叉树的基础是 “节点”,需包含数据域指针域(指向左 / 右子节点),Java 实现示例:

package com.heima.Tree; public class TreeNode { // 左子节点指针 public TreeNode lChild; // 右子节点指针 public TreeNode rChild; // 数据域(存储节点值) public Integer data; // 构造方法:初始化节点数据 public TreeNode(Integer data) { this.data = data; } }

2. 手动创建二叉树(以 “二叉搜索树” 为例)

通过create方法插入节点,遵循二叉搜索树规则(左子树值 < 父节点值 < 右子树值),实现逻辑(1)若树为空,新节点作为根节点;

(2)若树非空,从根节点开始比较:

1)新节点值 > 当前节点值 → 走右子树(直到右子树为空,插入新节点);

2)新节点值 < 当前节点值 → 走左子树(直到左子树为空,插入新节点)。

Java 实现示例:

public class BinaryTree { // 树的根节点指针 private TreeNode root; // 插入节点的方法 public void create(Integer value) { // 新建节点 TreeNode newNode = new TreeNode(value); // 情况1:树为空 → 新节点作为根 if (root == null) { root = newNode; return; } // 情况2:树非空 → 从根开始遍历插入 TreeNode curNode = root; while (true) { // 新节点值 > 当前节点值 → 走右子树 if (curNode.data < newNode.data) { // 右子树为空 → 插入新节点 if (curNode.rChild == null) { curNode.rChild = newNode; return; } // 右子树非空 → 继续遍历右子树 curNode = curNode.rChild; } // 新节点值 < 当前节点值 → 走左子树 else { // 左子树为空 → 插入新节点 if (curNode.lChild == null) { curNode.lChild = newNode; return; } // 左子树非空 → 继续遍历左子树 curNode = curNode.lChild; } } } }

3. 调用方法构建二叉树

创建BinaryTree对象,多次调用create方法插入节点,即可构建二叉树。示例(插入值5、3、7、8、4、6、9):

public static void main(String[] args) { BinaryTree bt = new BinaryTree(); bt.create(5); // 根节点 bt.create(3); // 5的左子节点 bt.create(7); // 5的右子节点 bt.create(8); // 7的右子节点 bt.create(4); // 3的右子节点 bt.create(6); // 7的左子节点 bt.create(9); // 8的右子节点 }

最终构建的二叉搜索树结构:

5 / \ 3 7 \ / \ 4 6 8 \ 9

三、二叉树的应用场景

二叉树(含其特殊结构)在多领域有核心作用:

(1)表达式树:表示数学表达式(如a*(b+c),根节点为*,左子树为a,右子树为(b+c));

(2)二叉搜索树:实现高效的 “增删查”(平均时间复杂度 O (logn));

(3)堆结构:实现优先队列(大顶堆 / 小顶堆),用于任务调度、TopK 问题等;

(4)哈夫曼编码树:数据压缩(如 ZIP 压缩),通过字符出现频率构建树,生成最短编码;(5)决策树:机器学习中用于分类 / 回归(如 ID3、C4.5、CART 树);

(6)平衡二叉树(如 AVL 树、红黑树):解决普通二叉搜索树的 “退化成链表” 问题,用于 JDK 集合(如TreeMap)。

四、创建二叉树的注意事项

(1)避免循环引用(如节点的左 / 右子节点指向自身或祖先节点);

(2)递归创建大二叉树时,注意栈溢出风险(可改用迭代方式);

(3)空节点的表示需统一(用null),避免逻辑混乱;

(4)不同的 “插入 / 遍历顺序” 会生成不同结构的二叉树(如同一组值,按不同顺序插入,二叉搜索树的形态会不同)。

五、二叉树的 4 种遍历方式

遍历的核心是 “按规则访问树中所有节点,且每个节点仅访问一次”。不同的遍历顺序对应不同的应用场景,我们逐一解析。

1. 先序遍历(Preorder Traversal)

(1)概念与规则

先序遍历的顺序是:根节点 → 左子树 → 右子树。优先访问当前节点,再递归处理左右子树。

(2)遍历步骤

1)访问当前根节点(如打印节点值);

2)递归遍历左子树;

3)递归遍历右子树。

(3)示例

以下二叉树的先序遍历结果为:A → B → D → E → C → F

A / \ B C / \ \ D E F
// 先序遍历(递归) public void preOrder(TreeNode root) { if (root == null) { return; } // 1. 访问根节点 System.out.println(root.data); // 2. 递归左子树 preOrder(root.lChild); // 3. 递归右子树 preOrder(root.rChild); }
(4)应用场景

1)目录结构打印(先输出当前目录,再遍历子目录);

2)表达式树生成前缀表达式(如+ A * B C);

3)树的序列化(保存树结构以便重建)。

(5)复杂度

1)时间复杂度:O(n)(每个节点访问一次);

2)空间复杂度:递归方式为O(h)(h 为树高),非递归方式最坏为O(n)

2. 中序遍历(In-order Traversal)

(1)概念与规则

中序遍历的顺序是:左子树 → 根节点 → 右子树。对于二叉搜索树(BST),中序遍历会得到升序的节点序列,这是其最核心的特性。

(2)示例

以下二叉树的中序遍历结果为:4 → 2 → 5 → 1 → 3

1 / \ 2 3 / \ 4 5
// 中序遍历(递归) public void inOrder(TreeNode root) { if (root == null) { return; } // 1. 递归左子树 inOrder(root.lChild); // 2. 访问根节点 System.out.println(root.data); // 3. 递归右子树 inOrder(root.rChild); }
(3)应用场景

1)二叉搜索树的升序遍历;

2)表达式树生成中缀表达式(如4 + 2 * 5);

3)编译原理中的语法树遍历。

3. 后序遍历(Postorder Traversal)

(1)概念与规则

后序遍历的顺序是:左子树 → 右子树 → 根节点。特点是 “最后访问根节点”,常用于 “先处理子节点,再处理父节点” 的场景。

(2)示例

以下二叉树的后序遍历结果为:D → E → B → F → C → A

A / \ B C / \ \ D E F
// 后序遍历(递归) public void postOrder(TreeNode root) { if (root == null) { return; } // 1. 递归左子树 postOrder(root.lChild); // 2. 递归右子树 postOrder(root.rChild); // 3. 访问根节点 System.out.println(root.data); }
(3)应用场景

1)表达式树计算结果(如(3+4)*5);

2)文件系统删除(先删子目录 / 文件,再删父目录);

3)内存释放(先释放子节点,再释放父节点)。

4. 层次遍历(Level Order Traversal)

(1)概念与规则

层次遍历也叫广度优先遍历(BFS),按 “层级顺序” 访问节点:从根节点开始,依次访问第 1 层、第 2 层…… 同一层从左到右访问。

实现依赖队列:先入队根节点,出队时访问该节点,并将其左右子节点入队,循环直到队列为空。

(2)示例:Java 实现(队列)
// 层次遍历(基于队列) public void levelOrder(TreeNode root) { if (root == null) { return; } // 创建队列,根节点入队 Queue<TreeNode> queue = new LinkedList<>(); queue.offer(root); while (!queue.isEmpty()) { // 出队并访问 TreeNode node = queue.poll(); System.out.println(node.data); // 左子节点入队 if (node.lChild != null) { queue.offer(node.lChild); } // 右子节点入队 if (node.rChild != null) { queue.offer(node.rChild); } } }
(3)应用场景

1)求二叉树的最小深度;

2)展示家族 / 组织的层级关系;

3)网络爬虫按链接层级抓取网页。

六、二叉搜索树的节点查询

对于二叉搜索树(BST),节点查询可以利用其 “左子树值 < 根节点值 < 右子树值” 的特性,实现高效查找(平均时间复杂度O(logn))。

(1)查询逻辑

1)若当前节点为空,返回null(未找到);

2)若当前节点值等于目标值,返回该节点;

3)若当前节点值 < 目标值,递归查询右子树;

4)若当前节点值 > 目标值,递归查询左子树。

(2)代码Java 实现

// 二叉搜索树节点查询 public TreeNode findNode(TreeNode root, Integer target) { // 树为空,未找到 if (root == null) { return null; } // 找到目标节点 if (root.data.equals(target)) { return root; } // 目标值更大,查右子树 else if (root.data < target) { return findNode(root.rChild, target); } // 目标值更小,查左子树 else { return findNode(root.lChild, target); } }

七、总结

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/9 18:53:31

QtC++定时3秒执行槽函数实战

记忆要点// 连接超时信号到槽函数QObject::connect(timer, &QTimer::timeout, &myObject, &MyClass::delayedSlot);1.QtC定时3秒执行槽函数实战在Qt C中实现3秒后执行槽函数&#xff0c;推荐使用QTimer的单次定时模式。以下是完整实现步骤和代码示例&#xff1a;核…

作者头像 李华
网站建设 2026/6/9 23:34:48

.NET 10 社区SDK(Loongarch 和 RISC-V)

一、Loongarch&#xff08;loongarch64 / Loongson&#xff09;上 .NET 10概览发布&#xff1a;v10.0.100-loongarch64&#xff08;tag&#xff09;发布者&#xff08;自动化&#xff09;&#xff1a;github-actions[bot]发布时间&#xff08;UTC&#xff09;&#xff1a;2025-…

作者头像 李华
网站建设 2026/6/10 14:00:46

【期末分析题与改错题】

文章目录一、程序分析题项目结构分析题01分析题02分析题03分析题04二、程序改错题项目结构改错题01改错题02改错题03改错题04改错题05改错题06一、程序分析题 项目结构 分析题01 代码&#xff1a; package ProgramAnalysis; /*** 1.定义一个二维数组arr&#xff0c;包含3行3…

作者头像 李华
网站建设 2026/6/9 23:52:18

每日八股——Go(4)

gRPC是什么&#xff1f; gRPC (Google Remote Procedure Call) 是一个由谷歌开发的高性能、开源的RPC&#xff08;远程调用&#xff09;框架。简单来说&#xff0c;他的核心目的是&#xff1a;让你调用远程服务器上的函数&#xff08;方法&#xff09;&#xff0c;就像调用本…

作者头像 李华
网站建设 2026/6/10 14:01:17

灌区PLC阀门远程监控运维系统方案

一、项目背景灌区作为农业用水的重要区域&#xff0c;其水资源的合理分配与高效利用直接关系到农业生产的稳定与发展。传统灌区管理方式中&#xff0c;PLC阀门往往依赖人工现场操作与监控&#xff0c;存在响应速度慢、管理效率低、资源分配不均等问题。随着物联网技术的发展&am…

作者头像 李华
网站建设 2026/6/10 13:59:18

Kubernetes集群升级指南

前言本文演示kubernetes集群从v1.24.1升级到v1.29.15。一、集群升级过程辅助命令&#xff08;1&#xff09;查看节点上运行的pod。kubectl get pod -o wide |grep <nodename>&#xff08;2&#xff09;查看集群配置文件。kubectl -n kube-system get cm kubeadm-config -…

作者头像 李华