数据结构-线索化二叉树 – leemoaly

关于具有n个打包的二叉树,敷用药双叉链存储器建筑学时,每个打包有两个指状物域和总共2n个指状物域。,而最适当的n-1个打包被无效指状物符号义(n个打包最适当的根打包不注意被无效指状物域符号义)

因而总社会团体n 1个空手指运动场。,形成空白表格变化无常的。

由两个树遍历发生物理反应的序列是一任一某一一次的序列。。假定这些空链域用于存储器前体和后部原动力,这样的事物走起来要便于使用的得多。。

把关联冠军:具有胸怀序列线索的两叉树的画漫画处置。对使后退便于使用的算法的变得流行。

鉴于不同的的穿越办法,不同的遍历一次的序列的发生物理反应。重行使明确两叉树的打包列举如下

typedef struct node
{    ElemType data;          //打包材料场int ltag,rtag;            //线索线索提升struct node *lchild;    //当LTAG=0时,LGEL表现左打包,LTAG=1未必代表左打包LFEL,它代表前体。struct node *rchild;    //当RTAG=0时,RPHAR表现好的的打包,RTAG=1表现不注意接受者打包。RSOR表现加入打包。
} TBTNode;//线索数打包典型的使明确

为了便于算法的设计,笔者在T中添加了另一任一某一头部打包。。头打包材料场是空的。,Lchild辨向不注意线索的根打包。,设置LTAG到0,RHOAD辨向已确定的遍历形式射中靶子期末考试一任一某一打包。,rtag=1。

遍历相同树的办法是不同的的。,也有不同的的线索树。。两叉树射中靶子三种序与后序,因而线索树也有一任一某一预先布置线索树。,胸怀序列线索树,三种后序线索树。

肉体美线索树的实质事实上的是遍历两个二元系。,在遍历跑过中,反省流传的的指状物运动场可能的选择,将它们替换成先锋打包或后置原动力打包。。

三线索二叉树

先序线索二叉树查找一任一某一打包的前序争吵打包罕有的简略,作为序文线索树 前提流传的打包为p,当p>rTAG==1时,笔者赚得p> >子代表加入打包。,此刻只需判别可能的选择辨向了头打包root若是代表p执意先序遍历射中靶子期末考试一任一某一打包。而当p->rtag==0若p->ltag==1则p的争吵打包执意p->rchild另外争吵打包是p->lchild。

头等遍历和搜索打包的序打包是不容易的。,你可以从第一任一某一线索中参观B。、在不赚得父打包的保持健康下,不克不及判别C的前缀打包。,关于DGEF,可以在不赚得父打包的保持健康下通行四点。。

后序线索树中也在同一的成绩。查找预排序打包是简略的,但不容易找到并下列U。。

终于,在现实敷用药中,优先的线索的敷用药较少地。,胸怀线索线索的相比。次排序线索射中靶子前体和争吵者的瞥见办法列举如下。

中序线索顺序的单步调试跑过

从上面的图片中,笔者赚得打包D将子点辨向HEA。,而D->ltag=1,因而笔者赚得D不注意兆头打包。,而D->rchild=G!=root且D->rtag==0而关于D的右子树说起最适当的一任一某一打包G因而G是D的后序打包另外应该是D的右子树中序遍历下的第一任一某一打包是D的争吵打包。

填写密码:

//名字:Exp7.5.CPP
#include 
#include <malloc.h>
#define MaxSize 100
typedef char ElemType;
typedef struct node
{    ElemType data;          //打包材料场int ltag,rtag;            //线索线索提升struct node *lchild;    //当LTAG=0时,LGEL表现左打包,LTAG=1未必代表左打包LFEL,它代表前体。struct node *rchild;    //当RTAG=0时,RPHAR表现好的的打包,RTAG=1表现不注意接受者打包。RSOR表现加入打包。
} TBTNode;//线索数打包典型的使明确
//到达两叉树void CreateTBTNode(TBTNode * &b,char *STR)
{    TBTNode ST [最大范围],*p=NULL;
    int top=-1,k,j=0;  
    char ch;
    b=NULL;                //所肉体美的两叉树在初始时期是空的。
    ch=STR〔J〕
    while (CH)!=''\0'')    //无扫描STR圈出
    {    switch(CH)) 
        {
        case''(''Top   ;St[top ]=p;k1; break;        //为左打包case'')'':top--;break;
        case'','':k=2; break;                    //右打包default:p=(TBTNode *)malloc(sizeof(TBTNode));
                p->data=ch;p->lchild=p->rchild=NULL;
                if (b==空)                    //P是两叉树的根打包
                    b=p;
                else//曾经肉体美了两个叉根打包。
                {    switch(k) 
                    {
                    case1St[Tope] > LCHORL= Pbreak;
                    case2St[Tope]>rCale=break;
                    }
                }
        }
        j++;
        ch=STR〔J〕
    }
}
//出口二叉树void DispTBTNode(TBTNode *b)
{    if (b!=空)
    {    printf("%c",b->材料)
        if (b->lchild!=NULL || b->rchild!=空)
        {    printf("(");
            DispTBTNode(b->孩童)
            if (b->rchild!=空) printf(",");
            DispTBTNode(b->rchild);
            printf(")");
        }
    }
}
TBTNode *pre;                        //全程变量void Thread(TBTNode *&p)
{    if (p!=空)
    {    穿成串(P)->孩童)            //左子树线索if (p->lchild==空)        //先锋线索
        {    p->lchild=pre;            //流传的打包的影响线索
            p->ltag=1;
        }
        else p->ltag=0;
        if (pre->rchild==空)        //后续线索
        {    pre->rchild=p;            //肉体美先锋打包的后续线索
            pre->rtag=1;
        }
        else pre->rtag=0;
        pre=p;
        穿成串(P)->rchild);            //右子树线索    }
}
//发生中序线索二叉树
TBTNode *CreateThread(TBTNode *b)        //中序线索二叉树
{    TBTNode *root;
    root=(TBTNode *)malloc(sizeof(TBTNode));    //到达根打包
    root->ltag=0;root->rtag=1;
    root->rchild=b;
    if (b==空)                //空二叉树
        root->lchild=root;
    else
    {    root->lchild=b;
        pre=root;                //PRE是*P的先锋打包,加线索
        穿成串(b)                //胸怀序列遍历线索二叉树
        pre->rchild=root;        //期末考试处置,向根打包添加线索
        pre->rtag=1;
        root->rchild=pre;        //根打包的右线索    }
    return root;
}
void InOrder(TBTNode 衰退期)        //按次算法呼唤{
    if (衰退期->lchild!=NULL && tb->ltag==0)    //有一任一某一左翼分子
        次(TB)孩童)
    printf("%c ",tb->材料)
    if (衰退期->rchild!=NULL && tb->rtag==0)    //有一任一某一恰当的的孩子
        次(TB)rchild);
}
void ThInOrder(TBTNode 衰退期)        //中线递归式算法{
    次(TB)->孩童)
}
void ThInOrder1(TBTNode 衰退期)    //中线非递归式算法
{    TBTNode *p=tb->lchild;        //点根打包while (p!=衰退期)
    {    while (p->ltag==0) p=p->lchild;
        printf("%c ",p->材料)
        while (p->rtag==1 && p->rchild!=衰退期)
        {    p=p->rchild;
            printf("%c ",p->材料)
        }
        p=p->rchild;
    }
}
void DestroyTBTNode1(TBTNode 衰退期)    //用DestroyTBTNode算法呼唤{
    if (衰退期!=空)
    {
        if (衰退期->lchild!=NULL && tb->ltag==0)  //有一任一某一左翼分子  
            DestroyTBTNode1(衰退期->孩童)
        if (衰退期->rchild!=NULL && tb->rtag==0)  //有一任一某一恰当的的孩子  
            DestroyTBTNode1(衰退期->rchild);
        free(衰退期);
    }
}
void DestroyTBTNode(TBTNode 衰退期)    //投递中序线索二叉树的每个人打包{
    DestroyTBTNode1(衰退期->孩童)
    free(衰退期);
}
void main()
{    TBTNode *b,*tb;
    CreateTBTNode(b,"A(B(D,E(H(J,K(L,M(,N))))),C(F,G(,I)))");     
    printf("二叉树:"DoptBtNoB(B)"\n");
    tb=Create穿成串(b)
    printf("线索序列次:\n");
    printf("    递归式算法:");Th次(TB));printf("\n");
    printf("  非递归式算法:");ThInOrder1(衰退期);printf("\n");
    DestroyTBTNode(衰退期);
}

线索