数据结构P4.4 二叉树的线索化

数据结构P4.4 二叉树的线索化

  • 普通二叉树遍历存在的缺点
    1.每一次必须要从根节点出发进行遍历,而线性表的遍历可以从任何一个结点进行后续遍历。
    2.以中序遍历为例:给定树中一个结点的指针,在树中找到前驱和后继结点很不方便

线索二叉树

  • 基于普通二叉树存在的不便之处,利用线索二叉树解决寻找树中某一结点的前驱和后继结点
  • 线索:指向前驱、后继的指针成为“线索”
  • 前驱线索:由左孩子指针充当
  • 后继线索:由右孩子指针充当
  • 中序线索二叉树:线索指向中序前驱、中序后继
  • 先序线索二叉树:线索指向先序前驱、先序后继
  • 后序线索二叉树:线索指向后序前驱、后序后继
为了区分是线索还是孩子结点
用tag标志;
tag=0 表示指针指向孩子;tag=1 表示指向线索
所以一个线索二叉树结点结构体可以表示为:
//线索二叉树结点结构体定义
typedef struct ThreadNode{
    ElemType data;
    struct ThreadNode *lchild,rchild;
    int ltag,rtag;                      /*左右线索标志位*/
}ThreadNode,ThreadTree;
下图是结构体逻辑示意图

在这里插入图片描述

二叉树的线索化

中序线索化

  • 利用中序遍历改造
//二叉树的结点(链式存储)
typedef struct BiTNode{
    char data;
    struct BiTNode *lchild, *rchild;    /*左右子结点*/
}BiTNode,*BiTree;

//辅助全局变量,用于查找给定结点p的前驱结点
BiTNode *p;                     /*p指向给定的目标结点*/
BiTNode *pre=NULL;              /*指向当前访问结点q的前驱结点*/
BiTNode *final=NULL;            /*用于记录最终结果*/

//中序遍历
void findPre(BiTree T){
    if(T!=NULL){
        findPre(T->lchild);    /*递归遍历左子树,结束条件为遇到空结点*/
        visit(T)                /*访问中间的根节点*/
        findPre(T->rchild);    /*递归遍历右子树,开始条件递归遍历左子树,结束条件为遇到空结点*/
    }
}

//访问当前的根节点q
void visit(BiTNode *q){
    if(q==p)                    /*目标结点指针p如果正好指向q*/
        final = pre;            /*找到p的前驱*/
    else
        pre=q;                  /*pre指向当前访问的结点*/
}
  • 中序线索化
//线索二叉树结点结构体定义
typedef struct ThreadNode{
    ElemType data;
    struct ThreadNode *lchild,rchild;
    int ltag,rtag;                      /*左右线索标志位*/
}ThreadNode,ThreadTree;


//全局变量pre,指向当前访问结点q的前驱
ThreadNode *pre=NULL;                   /*初始为NULL*/

//中序线索化二叉树T
void CreateInThread(ThreadTree T){
    pre= NULL;
    if (T!=NULL){                       /*非空二叉树才能线索化*/
        InThread(T);
        if (pre->rchild==NULL)
            pre->rtag=1;
    }
}

//中序遍历二叉树,一边遍历一边线索化
void InThread(ThreadTree T){
    if(T!=NULL){
        InThread(T->lchild);            /*中序遍历左子树*/
        visit(T);                       /*访问当前根结点*/
        InThread(T->rchild);            /*中序遍历右子树*/
    }
}

//访问当前的根节点q
void visit(ThreadNode *q){
    if(q->lchild==NULL){                /*左子树为空,建立前驱线索*/
        q->lchild=pre;
        q->ltag=1;                      /*tag=1,指向的是线索指针*/
    }
    
    if(pre!=NULL&&pre->rchild==NULL){
        pre->rchild=q;                 /*给前驱结点建立后继线索*/
        pre->rtag=1;                    /*修改标志*/
    }
    pre=q;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

kxwang_

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

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

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

打赏作者

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

抵扣说明:

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

余额充值