数据结构 线索二叉树 原理及实现

通过考察各种二叉链表,不管儿叉树的形态如何,空链域的个数总是多过非空链域的个数。准确的说,n各结点的二叉链表共有2n个链域,非空链域为n-1个,但其中的空链域却有n+1个。如下图所示。


    因此,提出了一种方法,利用原来的空链域存放指针,指向树中其他结点。这种指针称为线索。

    记ptr指向二叉链表中的一个结点,以下是建立线索的规则:

    (1)如果ptr->lchild为空,则存放指向中序遍历序列中该结点的前驱结点。这个结点称为ptr的中序前驱;

    (2)如果ptr->rchild为空,则存放指向中序遍历序列中该结点的后继结点。这个结点称为ptr的中序后继;

    显然,在决定lchild是指向左孩子还是前驱,rchild是指向右孩子还是后继,需要一个区分标志的。因此,我们在每个结点再增设两个标志域ltag和rtag,注意ltag和rtag只是区分0或1数字的布尔型变量,其占用内存空间要小于像lchild和rchild的指针变量。结点结构如下所示。


    其中:

    (1)ltag为0时指向该结点的左孩子,为1时指向该结点的前驱;

    (2)rtag为0时指向该结点的右孩子,为1时指向该结点的后继;

    (3)因此对于上图的二叉链表图可以修改为下图的养子。




#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
using namespace std;
typedef struct Binode
{
    char data;
    struct Binode *lchild,*rchild;
    int ltag,rtag;
} Binode,*Bitree;
Bitree pre;
void CreatTREE(Bitree &T)
{
    char ch;
    scanf("%c",&ch);
    if(ch==' ')
    {
        T=NULL;
    }
    else
    {
        T=(Bitree)malloc(sizeof(Binode));
        T->data=ch;
        T->ltag=0;
        T->rtag=0;
        CreatTREE(T->lchild);
        CreatTREE(T->rchild);
    }
    return;
}
void travel_threadtree(Bitree H)     //中序遍历线索树 从头节点开始
{
    Bitree p;
    p=H->lchild;                     //p为二叉树头节点
    while(p!=H)                       
    {
        while(p->ltag==0)            //有左子树 则 一直往下
            p=p->lchild;
        printf("%c ",p->data);       
        while(p->rtag==1&&p->rchild!=H)  //根据它的线索一直往后输出
        {
            p=p->rchild;
            printf("%c ",p->data);
        }
        p=p->rchild;                   //当没有线索时 表示有右子树
    }
    return;
}
void thread(Bitree T)               //线索化
{
    if(T)
    {
        thread(T->lchild);
        if(!T->lchild)
        {
            T->ltag=1;
            T->lchild=pre;
        }
        if(!pre->rchild)
        {
            pre->rtag=1;
            pre->rchild=T;
        }
        pre=T;                    //顺序是左子树 节点 右子树的中序遍历 所有 放这里
        thread(T->rchild);
    }
    return;
}
void threading_(Bitree &H,Bitree T)  //新增头节点
{
    H=(Bitree)malloc(sizeof(Binode));
    H->rchild=H;
    H->rtag=0;
    if(!T)                //二叉树为空
    {
        H->lchild=H;
        H->ltag=0;
    }
    else
    {
        pre=H;
        H->lchild=T;
        H->ltag=0;
        thread(T);
        H->rtag=1;
        H->rchild=pre;   //
        pre->rchild=H;    // 构成循环  以备跳出
    }
    return;
}
int main()
{
    Bitree T,H;
    CreatTREE(T);
    threading_(H,T);
    travel_threadtree(H); 
    return 0;
}





  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值