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

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

普通二叉链表:

  • 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. 中序线索树找前驱后继最简单,先序、后序很复杂


八、优缺点

优点

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

  • 非递归快速遍历

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

缺点

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

  • 树结构改动代价大

相关推荐
励志的小陈10 小时前
数据结构--二叉树知识讲解
数据结构
笨笨饿11 小时前
#58_万能函数的构造方法:ReLU函数
数据结构·人工智能·stm32·单片机·硬件工程·学习方法
li星野18 小时前
刷题:数组
数据结构·算法
故事和你9121 小时前
洛谷-数据结构-1-3-集合3
数据结构·c++·算法·leetcode·贪心算法·动态规划·图论
自我意识的多元宇宙1 天前
二叉树的遍历和线索二叉树--线索二叉树
数据结构
菜鸟丁小真1 天前
LeetCode hot100-287.寻找重复数和994.腐烂的橘子
数据结构·算法·leetcode·知识点总结
笨鸟先飞的橘猫1 天前
数据结构学习——跳表
数据结构·python·学习
Pentane.1 天前
【力扣hot100】【Leetcode 15】三数之和|暴力枚举 双指针 算法笔记及打卡(14/100)
数据结构·笔记·算法·leetcode