二叉树的遍历和线索二叉树--中序线索二叉树的构造

一、为什么要用线索二叉树

普通二叉链表:

  • n 个结点,一共2n 个指针域

  • 真正指向孩子的指针只有 n-1 个

  • 剩余 n+1 个空指针,空间浪费

解决办法:

利用空左、空右指针,存放中序遍历的前驱、后继结点

加上标记位区分,就是中序线索二叉树


二、线索结点结构

复制代码
数据 data
左指针 lchild  + 左标记 ltag
右指针 rchild  + 右标记 rtag
  • `ltag = 0`:lchild 指向左孩子

  • `ltag = 1`:lchild 是前驱线索

  • `rtag = 0`:rchild 指向右孩子

  • `rtag = 1`:rchild 是后继线索


三、构造核心规则(中序:左→根→右)

  1. 按照中序遍历顺序递归遍历整棵树

  2. 定义全局指针 `pre`,永远记录上一个访问过的结点

  3. 当前结点左孩子为空

→ 左指针指向 `pre`,`ltag=1`

  1. 前驱结点 `pre` 右孩子为空

→ pre 右指针指向当前结点,`pre.rtag=1`

  1. 遍历完当前结点,更新 `pre = 当前结点`

四、一步步构造流程(画图逻辑)

  1. 初始化 `pre = null`

  2. 递归线索化左子树

  3. 处理当前根结点:绑定前驱线索

  4. 绑定前驱结点到当前结点的后继线索

  5. 更新前驱 pre

  6. 递归线索化右子树


五、Java 标准构造代码

1.线索结点类

复制代码
class InThreadNode {
    int data;
    InThreadNode left;
    InThreadNode right;
    int ltag;   //0=左孩子  1=前驱线索
    int rtag;   //0=右孩子  1=后继线索

    public InThreadNode(int data) {
        this.data = data;
        left = null;
        right = null;
        ltag = 0;
        rtag = 0;
    }
}

2.中序线索化核心递归代码

复制代码
public class ThreadTree {
    static InThreadNode pre = null; //记录前驱结点

    //中序遍历实现二叉树线索化
    public void createInThread(InThreadNode root) {
        if (root == null) return;

        //1.递归线索化左子树
        createInThread(root.left);

        //2.处理当前结点:左空 → 指向前驱
        if (root.left == null) {
            root.left = pre;
            root.ltag = 1;
        }

        //3.处理前驱结点:右空 → 指向当前结点(后继)
        if (pre != null && pre.right == null) {
            pre.right = root;
            pre.rtag = 1;
        }

        //前驱后移
        pre = root;

        //4.递归线索化右子树
        createInThread(root.right);
    }
}

六、中序线索二叉树遍历(不用栈、不用递归)

复制代码
//线索树遍历
public void threadTraverse(InThreadNode root){
    InThreadNode p = root;

    //找到中序第一个结点(最左下)
    while(p != null && p.ltag == 0){
        p = p.left;
    }

    while(p != null){
        System.out.print(p.data + " ");

        //右是线索,直接走后继
        if(p.rtag == 1){
            p = p.right;
        }
        //右是孩子,找右子树最左下结点
        else{
            p = p.right;
            while(p != null && p.ltag == 0){
                p = p.left;
            }
        }
    }
}

七、考点

  1. 线索化本质 = 一次完整中序遍历

  2. `pre` 是连接前驱后继的关键

  3. 叶子结点:左右指针全部是线索

  4. 线索二叉树:无需递归、无需栈即可遍历

  5. n 个结点二叉链表,固定空指针数量:n+1 个

  6. 中序线索树找前驱后继最简单,先序、后序很复杂


八、优缺点

优点

  • 充分利用空闲指针,不额外占用空间

  • 非递归快速遍历

  • 快速查询结点遍历前驱、后继

缺点

  • 插入、删除结点麻烦,需要重新修改所有线索

  • 树结构改动代价大

相关推荐
qeen872 小时前
【数据结构】二叉树相关经典函数C语言实现
c语言·数据结构·c++·笔记·学习·算法·二叉树
良木生香3 小时前
【C++初阶】STL——List从入门到应用完全指南(1)
开发语言·数据结构·c++·程序人生·算法·蓝桥杯·学习方法
richard_yuu4 小时前
数据结构|二叉树高阶进阶-经典算法
数据结构·c++·算法
不知名的忻4 小时前
Dijkstra算法(朴素版&堆优化版)
java·数据结构·算法··dijkstra算法
YL200404266 小时前
027合并两个有序链表
java·数据结构·算法·链表
Zephyr_06 小时前
java数据结构
java·数据结构
xieliyu.7 小时前
Java手搓二叉树:基础遍历与核心操作全解析
java·开发语言·数据结构·学习
期待のcode7 小时前
Redis数据类型
运维·数据结构·redis
博界IT精灵7 小时前
图的遍历(哈喜老师)
数据结构·考研·算法·深度优先
所以遗憾是什么呢?8 小时前
【题解】Codeforces Round 1097 (Div. 2, Based on Zhili Cup 2026) (致理杯) ABCDEF
数据结构·算法·acm·codeforces·icpc·ccpc·xcpc