线索二叉树

1.基本概念


遍历二叉树实质上是对一个非线性结构进行线性化操作,使每一个结点在这些线性序列中有且仅有一个前驱和后继,当以二叉链表作为存储结构时,只能找到结点的左、右结点信息,而不能直接得到结点在任一序列中的前驱和后级信息,为此引入线索二叉树来保存这些在动态过程中得到的有关前驱和后继的信息。假设 以下序列为某个二叉树的中序遍历 " ANDFG” ,其中N的前驱是‘A’,后继是‘D’;

进行构造线索二叉树时,若结点有左子树,其中lchild 指向左孩子,否则令lchirld指向其前驱;

若结点有右子树,其中 rchild 指向右孩子,否则令 rchild指向其后继。其中指向前驱和后继的结点也叫线索。

其中 LTag={ 0       lchild指向结点的左孩子

                     1      lchild指向结点的前驱}

RTag = { 0              rchild指向结点的右孩子

              1               rchild质量结点的后继}

二叉树的二叉树线索类型定义如下:

typedef struct Bithrnode
{
   TElemType data;
   struct Bithrnode *lchild,*rchild;        //左右孩子指针
   int LTag,RTag;                           //左右是否有为空的标志
} Bithrnode,*Bithrtree;

2.构造线索二叉树:


线索二叉树的构造实质是将二叉链表中的空指针改为指向前驱和后继的线索,而前驱或后继的信息只有在遍历时才能得到,因此线索化的过程即在遍历的过程中修改空指针的过程。根据二叉树遍历方式不同,可以得到中序线索二叉树,先序线索二叉树,后序线索二叉树。

以结点p为根的子树中序线索化

(1)如果p非空,左子树递归线索化;

(2)如果p的左孩子为空,则给p加上左线索,将LTag置为1,让p的左孩子指针指向前驱pre,否则将p的LTag置为0;

(3)如果pre的右孩子为空,则给pre加上右线索,将RTag置为1,让pre的右孩子指针指向后继p,否则将RTag置为0;

(4)将pre指向刚访问过的结点p,即pre=p;

(5)右子树递归线索化。

算法描述:

void Inthreading(Bithrtree p)
{
    if(p)      
    {
        Inthreading(p->lchild);    //左子树线索化
        if(!p->lchild)     //p的左孩子为空则指向前驱pre
        {
            p->LTag=1;   //给p加上左线索
            p->lchild=pre;
        }
        else p->LTag=0;
        //就好比“ANDFG”其中 N的前驱为A,那么A的后继为N
        if(!pre->rchild)  //pre的右孩子为空指向后继p
        {
            pre->RTag=1; //给pre加上右线索
            pre->rchild=p;
            
        }
        else p->RTag=0;
        pre=p;
        Inthreading(p->rchild);  //右子树线索化
    }
}

3.遍历线索二叉树

A.在中序线索二叉树中查找

(1)查找p指针所指结点的前驱

若p->LTag=1,则p的左链指向其前驱;

若p->LTag=0,则说明p有左子树,结点的前驱是遍历左子树时最后访问的一个结点;

(2)查找p指针所指的后继结点

若p->RTag=1,则p的右链指向其后继;

若p->RTag=0,则说明p有右子树,结点的后继是遍历其右子树时访问的第一个结点,即右子树中最左下的结点。

B.在先序线索二叉树中查找:

(1)查找p指针所指结点的前驱

若p->LTag=1,则p的左链指向其前驱;

若p->LTag=0,则说明p有左子树,此时p的前驱有两种情况,若p是双亲的左孩子,则其前驱为其双亲结点;否则是其双亲的左子树上先序遍历最后访问的结点;

(2)查找p指针所指的后继结点

若p->RTag=1,则p的右链指向其后继;

若p->RTag=0,则说明p有右子树,p的后继必然为其左子树根(若存在)或右子树根。

 C.  后序线索二叉树中查找:

(1)查找p指针所指结点的前驱

若p->LTag=1,则p的左链指向其前驱;

若p->LTag=0,当p->RTag=0时,p的右链指向其前驱;若p->LTag=0,p->RTag=1时,p的左链指向其前驱;

(2)查找p指针所指的后继结点

若p是二叉树的根,则其后继为NULL;

若p是双亲的右孩子,则其后继为双亲结点;

若p是其双亲的左孩子,则p没有右兄弟,其后继为双亲结点;

若p是其双亲的左孩子,且p有右兄弟,则其后继为双亲的右子树上按后序遍历列出的第一个结点。

遍历中序线索二叉树:
 

void Inordertraverse(Bithrtree T)
{
    p=T->lchild; //p指向根结点
    while(p!=T)
    {
        while(p->LTag==0) p=p->lchild;  //左子树
        printf("%d ",p->data);         
        while(p->RTag==1&&p->rchild!=T)  //沿右线索访问后继结点
        {
            p=p->rchild;
            printf("%d ",p->data);
        }
        p=p->rchild;    //右子树
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
创建线索叉树是一种对二叉树进行优化的数据结构。它的目的是为了加快二叉树的遍历速度。在传统的二叉树中,为了实现对二叉树的遍历,需要使用递归或者栈来实现。而线索叉树通过添加线索,将二叉树的节点之间的遍历顺序进行编码,从而实现快速遍历。 在线索叉树中,每个节点都有两个指针:左指针和右指针。在一棵二叉树中,如果一个节点没有左孩子,则将其左指针指向该节点的前驱节点。如果一个节点没有右孩子,则将其右指针指向该节点的后继节点。通过这样的线索指针,可以快速地找到一个节点的前驱和后继节点,进而实现对二叉树的快速遍历。 具体来说,在线索叉树中,如果一个节点没有左孩子,则将其左指针指向其前驱节点;如果一个节点没有右孩子,则将其右指针指向其后继节点。通过这样的线索化过程,原本需要递归或者栈来实现的遍历过程,可以直接通过线索指针快速找到下一个需要遍历的节点,从而提高了遍历的效率。 总的来说,线索叉树是一种优化的二叉树结构,通过添加线索指针,将二叉树的节点之间的遍历顺序进行编码,从而实现了对二叉树的快速遍历。它的设计思想主要是通过设置节点的线索指针指向前驱和后继节点,提高了遍历效率,减少了递归或栈的使用。这是一个在实际应用中常用的数据结构,可以广泛应用于二叉树遍历的场景中。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值