《Java数据结构与算法》第四篇(二)二叉树的性质、定义与链式存储实现

二叉树的性质、定义与链式存储实现

前言:今天我们来深入学习数据结构中的重要概念------二叉树。作为树形结构中最基础也是最重要的类型,二叉树在计算机科学中有着广泛的应用。本文将从基本概念出发,重点讲解二叉树的链式存储实现。

一、什么是二叉树?

1.1 二叉树的定义

二叉树是每个节点最多有两个子树的有序树,通常子树被称作"左子树"和"右子树"。

特点:

  • 每个节点最多有两个子节点(度≤2)
  • 子树有左右之分,次序不能颠倒
  • 二叉树可以是空树,也可以是由根节点和左右子树组成

1.2 二叉树的基本性质

性质1: 在二叉树的第i层上最多有2^(i-1)个节点(i≥1)

性质2: 深度为k的二叉树最多有2^k - 1个节点(k≥1)

性质3: 对于任何一棵二叉树,如果其终端节点数为n₀,度为2的节点数为n₂,则n₀ = n₂ + 1

性质4: 具有n个节点的完全二叉树的深度为⌊log₂n⌋ + 1

二、二叉树的存储表示

2.1 顺序存储结构

顺序存储适用于完全二叉树,使用数组来存储节点:

java 复制代码
// 顺序存储示例(仅展示概念)
// 节点i的左孩子:2i,右孩子:2i+1,父节点:i/2
// 数组索引:[0, 1, 2, 3, 4, 5, 6, 7]
// 对应节点:[A, B, C, D, E, F, G, H]

优点:

  • 存储空间利用率高
  • 节点关系明确,通过下标计算即可获得父子关系

缺点:

  • 对于非完全二叉树,空间浪费严重
  • 插入、删除操作不方便

2.2 链式存储结构(重点!)

链式存储是二叉树最常用的存储方式,每个节点包含数据域和指向左右孩子的指针域。

三、二叉树链式存储的Java实现

下面我们来看完整的链式存储实现:

java 复制代码
package chapter4;

public class BiTree {
    BiTreeNode root;  // 根节点
    int num;          // 节点总数

    public BiTree() {
        root = new BiTreeNode();
        num = 0;
    }

    private int pi = 0;

    // 创建二叉树的公共接口
    public void createBiTree(String input) {
        pi = 0;  // 重置位置指针
        root = createBiTreeHelper(input);
        num = countNodes(root);  // 统计节点数
    }

    // 递归创建二叉树的辅助方法
    private BiTreeNode createBiTreeHelper(String input) {
        if(pi >= input.length() || input.charAt(pi) == '#') {
            pi++;  // 跳过'#'
            return null;  // 空节点
        }

        // 创建当前节点
        BiTreeNode root = new BiTreeNode(input.charAt(pi));
        pi++;  // 移动到下一个字符

        // 递归创建左子树
        root.lchild = createBiTreeHelper(input);

        // 递归创建右子树
        root.rchild = createBiTreeHelper(input);

        return root;
    }

    // 计算节点总数的递归方法
    private int countNodes(BiTreeNode root) {
        if(root == null) {
            return 0;
        }
        // 1(当前节点) + 左子树节点数 + 右子树节点数
        return 1 + countNodes(root.lchild) + countNodes(root.rchild);
    }
}

// 二叉树节点类
class BiTreeNode {
    char data;              // 数据域
    BiTreeNode lchild;      // 左孩子指针
    BiTreeNode rchild;      // 右孩子指针

    // 无参构造函数
    public BiTreeNode() {
    }

    // 带数据的构造函数
    public BiTreeNode(char data) {
        this.data = data;
        lchild = null;
        rchild = null;
    }

    // 完整构造函数
    public BiTreeNode(char data, BiTreeNode lchild, BiTreeNode rchild) {
        this.data = data;
        this.lchild = lchild;
        this.rchild = rchild;
    }
}

代码详解

3.1 核心设计思想

  1. 节点设计BiTreeNode类采用经典的"数据域 + 左孩子 + 右孩子"三要素设计
  2. 递归创建:使用先序遍历的思想递归构建二叉树
  3. 空节点标记:使用'#'字符表示空节点,这是二叉树序列化的常用技巧

3.2 关键方法解析

createBiTreeHelper方法解析:

java 复制代码
private BiTreeNode createBiTreeHelper(String input) {
    if(pi >= input.length() || input.charAt(pi) == '#') {
        pi++;  // 别忘了移动指针!
        return null;
    }

    BiTreeNode root = new BiTreeNode(input.charAt(pi));
    pi++;  // 处理完当前字符后移动

    // 先序遍历:根 → 左 → 右
    root.lchild = createBiTreeHelper(input);
    root.rchild = createBiTreeHelper(input);

    return root;
}

输入示例: 对于字符串 "ABD##E##CF##G##"

  • A:根节点
  • B:A的左孩子
  • D:B的左孩子
  • ##:D的左右孩子都为空
  • E:B的右孩子
  • ##:E的左右孩子都为空
  • 以此类推...

3.3 技术亮点

  1. 递归思想:整个创建过程体现了递归的优雅
  2. 边界处理:正确处理了空节点和越界情况
  3. 节点统计:通过递归精确计算节点总数
  4. 封装设计:将递归细节封装在私有方法中,提供简洁的公共接口

四、应用场景

这种链式存储实现适用于:

  • 表达式树的构建和计算
  • 哈夫曼树的构造
  • 二叉搜索树的操作
  • AVL树红黑树等平衡树的实现

五、总结

通过本文的学习,我们掌握了:

  1. 二叉树的基本性质和定义
  2. 顺序存储与链式存储的对比
  3. 链式存储的完整Java实现
  4. 递归创建二叉树的核心技巧

二叉树的链式存储虽然需要额外的指针空间,但其灵活性和操作便利性使其成为实际应用中的首选存储方式。


💪 学习建议: 动手实现这个代码,尝试不同的输入字符串,观察二叉树的构建过程。理解递归在树结构中的重要作用,这将为后续学习更复杂的树形结构打下坚实基础!

下期预告:二叉树的便利

如果觉得本文对你有帮助,别忘了点赞👍收藏❤️关注哦!有什么问题欢迎在评论区讨论交流!

相关推荐
你不是我我8 小时前
【Java 开发日记】我们来说一下消息的可靠性投递
java·开发语言
风月歌8 小时前
小程序项目之“健康早知道”微信小程序源码(java+小程序+mysql)
java·微信小程序·小程序·毕业设计·源码
乌萨奇也要立志学C++8 小时前
【洛谷】贪心专题之哈夫曼编码 从原理到模板题解析
c++·算法
czlczl2002092510 小时前
告别 try-catch 地狱:Spring Boot 全局异常处理 (GlobalExceptionHandler) 最佳实践
java·spring boot·后端
Goldn.16 小时前
Java核心技术栈全景解析:从Web开发到AI融合
java· spring boot· 微服务· ai· jvm· maven· hibernate
fie888917 小时前
NSCT(非下采样轮廓波变换)的分解和重建程序
算法
李慕婉学姐17 小时前
【开题答辩过程】以《基于Android的出租车运行监测系统设计与实现》为例,不知道这个选题怎么做的,不知道这个选题怎么开题答辩的可以进来看看
java·后端·vue
m0_7400437317 小时前
SpringBoot05-配置文件-热加载/日志框架slf4j/接口文档工具Swagger/Knife4j
java·spring boot·后端·log4j
编织幻境的妖17 小时前
SQL查询连续登录用户方法详解
java·数据库·sql