线索二叉树详细解释

全知识整理目录

数据结构整理的目录包括了许多的数据结构相关知识。


目录

概述

需要了解的概念 

实例

代码实现


概述

什么是线索二叉树?

为了区分二叉树的左孩子指针,和右孩子指针是否为空,为结点增加了2个域,这两个域分别是Ltag和Rtag。这样的二叉树,就是线索二叉树。

需要了解的概念 

如果结点有左孩子:那么Lchild指向他的左孩子,否则指向遍历序列中他的前驱结点。

如果结点有右孩子:那么Rchild依然指向他的左孩子,否则指向遍历序列的后继节点。

Ltag=0:表示Lchild指向结点的左孩子。

Ltag=1:表示Lchild指向结点的遍历前驱。

Rtag=0:表示Rchild指向结点的左孩子。

Rtag=1:表示Rchild指向结点的遍历后继。 

ps:0左,1前后。

线索:指向前驱和后继结点的指针。

线索化:将空指针改为线索的过程。

实例

如下图二叉树实例,先后进行先序,中序,后序。

其实无论是什么样的序列化,只需要记得下面这三句话:

  • 如果结点有左孩子:那么Lchild指向他的左孩子,否则指向遍历序列中他的前驱结点。
  • 如果结点有右孩子:那么Rchild依然指向他的左孩子,否则指向遍历序列的后继节点。
  • 前驱或者后驱没有,就为NULL。

先序

 中序

 后序

 上述二叉搜索树的过程实现,只需要记住开始的那几句话,就基本能够实现了。

代码实现

如何使用代码实现,先,中,后序的二叉序列树。

下面以中序线索化为例:

首先遍历到,左孩子指针域为空的时候,这时候就要访问他的前驱结点,所以需要定义一个全局的pre来记录刚刚访问过的结点,将pre赋给他的左孩子域,将Ltag设置为1。

当遍历到右孩子指针域为空的时候,要填写的结点应该是,该结点的后续结点,但是当前无法确认后继节点,因此当前节点右孩子的指针域,只能遍历到下一个结点的时候在填写,并且当前结点就是pre结点的后继结点,所以需要回填pre,如果pre的右孩子结点为空,那么当前的结点赋值给pre右节点,同时pre结点的Rtag设置为1。

#define pre 

void mid_thiread(BiThree root)
{
    if(root!=NULL)
    {
        mid_thiread(root->Lchild);    //递归线索化root的左孩子
        if(root->Lchild == NULL)     //左孩子为空,则指向他的前驱pre
        {
            root->Lchild = pre;
            root->Ltag = 1;
        }
        else{
            root->Ltag = 0;    //左孩子不为空,Ltag=0;
        }
        if(pre != NULL && pre->Rchild == NULL)    //右孩子为空,指向他的后继
        {
            pre->Rchild =root;
            pre->Rtag =1;
        }
        pre = root;
        mid_thiread(root->Rchild);    //递归线索化root右孩子
    }
}

中序线索二叉树,寻找首结点

首先访问的是,往最左下端走,找到的第一个没用左孩子的结点。

BiTree InFirst(BiTree bt){
    //寻找最左下角,第一个没有左孩子的结点
    BiTree p =bt;
    if(p == NULL)
        return NULL;
    while(p->Ltag == 0)
        p = p->Lchild;
    return p;
}

寻找结点的后继

寻找,后继结点,就是寻找到后续第一个没有左孩子的结点。

BiTree in_next(BiTree p){

    BiTree next,q;
    if(p->Rtag == 1)
    {
        next = P->Rchild;   //使用线索化 
    }
    else
    {
        for(q = p->Rchild; q->Ltag == 0; q = q->Lchild);
        next = q;
    }
    return(next);
}

参考博客

线索化二叉树

  • 4
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ybbgrain

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值