二叉树(二)

五、线索二叉树

    当以二叉链表作为存储结构时,只能找到结点的左、右孩子信息,而不能直接得到结点在任一序列中的前驱和后继信息,

    这种信息只有在遍历的动态过程中才能得到。

    

                                                                   线索二叉树结点结构

       规定:

                若结点有左子树,则其LChild域指向其左孩子,否则LChild域指向其前驱结点;

                若结点有右子树,则其RChild域指向其右孩子,否则RChild域指向其后继结点。

       其中:

                LTag:

                        0----LChild域指向结点的左孩子

                        1----LChild域指向结点的遍历前驱

                RTag:

                        0----RChild域指向结点的右孩子

                        1----RChild域指向结点的遍历后继

        在这种存储结构中,指向前驱和后继的结点的指针称为线索。以这种结构组成的二叉链表作为二叉树的的存储结构,

        称为线索链表。对二叉树以某种次序进行遍历并且加上线索的过程称为线索化。线索化了的二叉树称为线索二叉树。

        实质:

                将二叉链表中的空指针域上填上相应结点的遍历前驱或遍历后继结点的地址,而前驱和后继的地址只能在动态的

                遍历过程中才能得到,因此线索化的过程即为在遍历过程中修改空指针域的过程。

        建立中序线索树:

                 (1)算法思想:

                            设置一个指针pre,始终记录刚访问过的结点。

                                    如果当前遍历结点root的左子域为空,则让左子域指向pre;

                                   如果前驱pre的右子域为空,则让右子域指向当前遍历结点root;

                                   为下次做准备,当前访问结点root作为下一个访问结点的前驱pre。 

                 (2)算法描述:                

                            void  Inthread(BiTree  root)

                            {

                                    if(root != NULL)

                                    {

                                            Inthread(root->LChild);    //线索化左子树

                                            if(root->LChild == NULL)

                                            {

                                                    root->LTag = 1;

                                                    root->LChild = pre;

                                            }

                                           if(pre != NULL && root->RChild == NULL)

                                          {

                                                   pre->RChild = root;

                                                   pre->RTag = 1;

                                          }

                                          pre = root;      //当前访问结点为下一个访问结点的前驱

                                         Inthread(root->RChild);        //线索化右子树

                                    }

                            }

           在线索二叉树中找前驱结点

                        (1)算法思想

                             对于结点p,当p->LTag = 1时,p->LChild指向p的前驱;当p->LTag = 1时,p->LChild指向p的左孩子。

                             作为根p的前驱结点,它是中序遍历p的左子树时访问的最后一个结点,即左子树的“最右下端”结点。

                        (2)算法描述

                              BiTNode*  InPre(BiTNode* p)

                             {

                                        if(p->LTag == 1)

                                        {

                                                pre = p->LChild;

                                        }

                                       else

                                        {

                                                for(q = p->LChild;q->RTag == 0;q = q->RChild)

                                                {

                                                        pre = q;

                                                }

                                        }

                                      return pre;

                             }

           在线索二叉树中找后继结点

                        (1)算法思想

                                   对于结点p,若p->RTag = 1时,p->RChild即为p的后继结点;当p->RTag = 0时,说明p有右子树,

                                   此时p的中序遍历后继结点为其右子树的“最左下端”的结点。

                        (2)算法描述

                                   BiTNode*   InNext(BiTNode  *p)

                                  {

                                            if(p->RTag == 1)

                                            {

                                                    next = p->RChild;

                                            }

                                           else

                                           {

                                                    for(q = p->RChild;q->LTag == 0;q = q->LChild)

                                                    {

                                                            next = q;

                                                    }

                                            }

                                           return next;

                                 }

           遍历中序线索树

                       (1)算法思想

                                求出某种遍历次序下第一个被访问结点;

                                然后连续求出刚访问结点的后继结点,直至所有的结点均被访问。

                       (2)算法描述

                                BiTNode*  InFirst(BiTree bt)

                                {

                                       BiTNode *p = bt;

                                       if(p =- NULL)

                                       {

                                                return NULL;

                                        }

                                       while(p->LTag == 0)

                                        {

                                                p = p->LChild;

                                        }

                                        return p;

                                }                

                

                                void TInOrder(BiTree bt)

                                {

                                        BiTNode * p;

                                        p = InFirst(bt);

                                        while(p != NULL)

                                        {

                                                visit(p);

                                                p = InNext(p);

                                        }

                                }

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值