树结构技术学习笔记

一、基础概念

1. 二叉树基础

树是典型的非线性数据结构,二叉树 是树结构中最常用的类型,规则为:每个节点最多拥有两个子节点,分别称为左子节点、右子节点,左右节点顺序不可颠倒。

1.1 节点存储结构

二叉树的核心存储单元为节点(TreeNode),每个节点包含三部分:

  • 数据域:存储节点数据
  • 左子节点引用:指向左孩子
  • 右子节点引用:指向右孩子
1.2 辅助概念:Hash算法

Hash 算法可将任意类型的数据计算出唯一哈希值,本案例中借助哈希值大小作为二叉搜索树的排序依据,实现节点有序存放。

二、二叉搜索树(排序二叉树)实现

二叉搜索树(BST)属于二叉树的衍生结构,核心规则:

  1. 左子树所有节点哈希值 < 当前节点哈希值
  2. 右子树所有节点哈希值 ≥ 当前节点哈希值
  3. 左右子树同样遵循上述规则

下面结合源码补全、修正代码,并添加详细注释。

2.1 完整代码实现

java 复制代码
package com06.dc.zyf0606;

// 二叉树节点类
public class TreeNode<E> {
    E data;                // 节点存储的数据
    TreeNode<E> left;      // 左子节点引用
    TreeNode<E> right;     // 右子节点引用

    // 构造方法:初始化节点数据,左右子节点默认为null
    public TreeNode(E data) {
        this.data = data;
    }
}

// 二叉搜索树主体类
class Tree<E> {
    TreeNode<E> root;  // 根节点 // 整棵树的入口
    int size;          // 树中节点总数量

    // 添加节点方法:按照哈希值大小插入,构建二叉搜索树
    public void add(E data) {
        TreeNode<E> node = new TreeNode<>(data);
        // 树为空,直接将新节点设为根节点
        if (root == null) {
            root = node;
            size++;
            return;
        }
        TreeNode<E> temp = root;
        // 循环遍历寻找合适的插入位置
        while (temp != null) {
            // 对比哈希值:当前节点哈希值更大,新节点放左子树
            if (temp.data.hashCode() > data.hashCode()) {
                // 左子节点为空,直接插入
                if (temp.left == null) {
                    temp.left = node;
                    size++;
                    break;
                } else {
                    // 左子节点不为空,继续向左遍历
                    temp = temp.left;
                }
            } else {
                // 新节点哈希值更大/相等,新节点放右子树
                if (temp.right == null) {
                    temp.right = node;
                    size++;
                    break;
                } else {
                    // 右子节点不为空,继续向右遍历
                    temp = temp.right;
                }
            }
        }
    }

    // 删除节点(待实现):二叉搜索树删除需处理三种情况,难点为找右子树最小节点
    public void remove(E data) {
        // 核心思路:删除非叶子节点时,使用【右子树最小节点】替代当前节点
    }

    // 查询节点(待实现):根据数据查找对应节点
    public void get(E data) {

    }

    // 递归遍历:后序遍历(左->右->根)
    private void print(TreeNode<E> temp) {
        // 递归终止条件:节点为空,直接返回
        if (temp == null) {
            return;
        }
        print(temp.left);       // 递归遍历左子树
        print(temp.right);      // 递归遍历右子树
        System.out.print(temp.data + " , "); // 打印当前节点数据
    }

    // 对外提供的遍历方法,入口为根节点
    public void printTree() {
        print(root);
    }

    // 主方法:测试二叉搜索树
    public static void main(String[] args) {
        // 测试数据数组
        String[] arr = {
                "hello3859",
                "hello227",
                "hello3327",
                "hello7885",
                "hello6953",
                "hello7066",
                "hello7678",
                "hello8134",
                "hello8844",
                "hello9459"
        };
        Tree<String> tree = new Tree<>();
        // 循环添加数据到二叉搜索树
        for (int i = 0; i < arr.length; i++) {
            tree.add(arr[i]);
        }
        // 遍历打印整棵树
        tree.printTree();
    }
}

2.2 代码补充说明

  1. 遍历方式 :代码中 print 方法为后序遍历,二叉树还有前序(根→左→右)、中序(左→根→右)两种常用递归遍历;
  2. 与Set集合关联 :二叉搜索树天然具备数据不重复、无序存储 的特点,和 Java 中 Set 集合特性一致,部分 Set 底层基于二叉搜索树实现;
  3. 分层存储思路 :可借助动态数组,将二叉树每一层节点单独存入一个数组,数组数量等于树的高度,实现层序存储与层序遍历。

三、常见树结构分类、特性与应用场景

1. 普通二叉树

特性
  1. 每个节点最多两个子节点,无排序规则;
  2. 节点分布随机,查询、增删效率不稳定;
  3. 分为满二叉树、完全二叉树两个特殊子类。
应用场景
  1. 表达层级关系:文件目录、组织机构、家谱等;
  2. 简单层级数据展示、图形界面的树形菜单。

2. 二叉搜索树(BST)

特性
  1. 遵循左小右大排序规则,基于哈希值/自定义比较器排序;
  2. 理想状态下查询、插入、删除时间复杂度为 O(log n);
  3. 极端情况会退化为单链表(如顺序插入数据),效率降至 O(n)。
应用场景
  1. 基础有序数据查找、排序;
  2. 早期部分有序集合、索引结构的底层实现。

3. 平衡二叉树(AVL树)

特性
  1. 在二叉搜索树基础上增加平衡条件:左右子树高度差绝对值不超过 1;
  2. 节点增删后会自动旋转调平,杜绝退化为链表的问题;
  3. 查询效率稳定 O(log n),但频繁旋转会增加增删开销。
应用场景
  1. 查询操作远多于增删操作的场景;
  2. 数据库部分索引、高频查询的有序数据结构。

4. 红黑树

特性
  1. 自平衡二叉搜索树,通过节点染色+旋转维持平衡;
  2. 平衡规则比 AVL 树宽松,旋转次数更少,增删效率更高;
  3. 最长路径不超过最短路径的 2 倍,查询效率稳定 O(log n)。
应用场景
  1. Java TreeMapTreeSet 底层核心结构;
  2. C++ STL 中的 map、set;
  3. Linux 内核进程调度、内存管理。

5. 堆(二叉堆)

特性
  1. 属于完全二叉树,分为大顶堆小顶堆
  2. 大顶堆:父节点值 ≥ 所有子节点值;小顶堆:父节点值 ≤ 所有子节点值;
  3. 底层常用数组存储,不依赖指针。
应用场景
  1. 优先级队列(Java PriorityQueue 底层);
  2. 堆排序算法、TopK 问题(找出最大/最小前 K 个元素);
  3. 任务优先级调度。

6. B树 / B+树(多路平衡查找树)

特性
  1. 多路平衡树,一个节点可包含多个子节点和多个数据,不再限制为二叉;
  2. 节点关键字有序,所有叶子节点处于同一层级;
  3. B+树所有数据仅存于叶子节点,非叶子节点只做索引。
应用场景
  1. 数据库索引(MySQL、Oracle 主流索引结构);
  2. 磁盘文件系统索引,适配磁盘块读写特性,减少 IO 次数。

7. 哈夫曼树(最优二叉树)

特性
  1. 带权路径长度最短的二叉树,又称最优二叉树;
  2. 只有度为 0 和 2 的节点,无单独左/右子节点;
  3. 根据权重构建,权重越大的节点离根节点越近。
应用场景
  1. 哈夫曼编码(数据压缩,如文本、图片压缩算法);
  2. 报文编码、传输加密场景。

8. 字典树(Trie树)

特性
  1. 又称前缀树,专门处理字符串;
  2. 公共前缀字符串共享节点,节点仅存储单个字符;
  3. 查询字符串前缀效率极高。
应用场景
  1. 输入法联想提示、单词前缀匹配;
  2. 搜索引擎关键词补全、字符串检索、敏感词过滤。

四、总结

  1. 二叉树是所有树形结构的基础,二叉搜索树引入排序规则,解决有序数据查找问题;
  2. 为优化二叉搜索树的缺陷,衍生出 AVL 树、红黑树等平衡树,适配不同读写场景;
  3. 多路树(B/B+树)主打磁盘存储与大数据索引,堆偏向优先级排序,字典树专攻字符串处理;
  4. 实际开发中根据数据类型、读写频率、存储介质选择对应树结构,是选型的核心依据。
相关推荐
十月的皮皮2 小时前
C语言学习笔记202606008- 三角形判断(3种方法)
c语言·笔记·学习
XGeFei2 小时前
【Fastapi学习笔记(6)】—— Fastapi文件上传、请求头自动转换
笔记·学习·fastapi
小欣加油2 小时前
leetcode2161 根据给定数字划分数组
数据结构·c++·算法·leetcode·职场和发展
雨落在了我的手上2 小时前
Java数据结构(四):List的介绍
数据结构
大都督会赢的2 小时前
数据结构(2)--单链表
数据结构
嘶哈哈哈2 小时前
嘉立创 EDA 入门实操笔记:从原理图到 PCB 布线、差分对、覆铜与 DRC 检查
开发语言·笔记·php
一口吃俩胖子2 小时前
【脉宽调制DCDC功率变换学习笔记024】频域性能
笔记·学习
吃着火锅x唱着歌2 小时前
深度探索C++对象模型 学习笔记 第五章 构造、解构、拷贝语意学(2)
c++·笔记·学习
中小企业实战军师刘孙亮3 小时前
快消纺织五金怎么融合?三大业态协同发展战略思路-佛山鼎策创局破局增长咨询
学习·面试·创业创新·制造·学习方法