线索化二叉树

来源:互联网 发布:VPN软件百度云 编辑:程序博客网 时间:2024/06/06 15:27

线索化二叉树等于把一棵树转变成一个双向链表,这样对我们插入、删除结点,查找某个结点带来方便。
每个结点增加两个标志Ltag和Rtag,结点结构如下
线索化的过程实质是将二叉链表的空指针改为指向前驱和后继的线索,由于前驱和后继的信息只有在遍历的过程中才能得到。所以,线索化的过程就是在遍历的过程中修改空指针的过程。

typedef enum{Link=0,Thread=1} PointTag;  //Link=0表示左右孩子指针                                         //Thread=1表示指向前驱或后继线索;typedef struct BiThrNode{    BiThrNode *leftchild;    BiThrNode *rightchild;    PointTag Ltag,Rtag;    ElemType data;}BiThrNode,* ThreadBinaryTree;BiThrNode * Buynodes(){    BiThrNode *s = (BiThrNode*)malloc(sizeof(BiThrNode));    if(s == NULL) exit(1);    memset(s,0,sizeof(BiThrNode));    return s;}BiThrNode * CreateThr(char *&str)   {    BiThrNode *s = NULL;    if(*str !='#')    {        s = Buynodes();        s->data = *str;        s->Ltag = s->Rtag = Link;        s->leftchild = CreateThr(++str);        s->rightchild = CreateThr(++str);    }    return s;}BiThrNode * CreateThrTree(char *str)   //创建二叉树{    if(str == NULL)        return NULL;    else         return CreateThr(str);}//中序遍历进行线索化(递归)void Make(BiThrNode *ptr,BiThrNode *&p)   {    if(ptr != NULL)    {        Make(ptr->leftchild,p); //递归左子树线索化        if(ptr->leftchild == NULL)        {            ptr->leftchild = p;    //前驱线索            ptr->Ltag = Thread;  //左孩子指向前驱        }        if(p != NULL && p->rightchild == NULL)                                    //前驱没有右孩子        {            p->rightchild = ptr;  //后继线索            p->Rtag = Thread;   //前驱右孩子指向后继        }        p = ptr;    //保持p指向ptr前驱;        Make(ptr->rightchild,p);  //递归右子树线索化    }}void MakeThreadTree(BiThrNode *ptr)   {    BiThrNode *p = NULL;    Make(ptr,p);    p->rightchild = NULL;    p->Rtag = Thread;}void MakePre(BiThrNode *ptr,BiThrNode *&p)   //前序线索化{    if(ptr != NULL)    {        MakePre(ptr->leftchild,p);        if(ptr->leftchild == NULL)        {            ptr->leftchild = p;            ptr->Ltag = Thread;        }        if(p != NULL && p->rightchild == NULL)        {            p->rightchild = ptr;            p->Rtag = Thread;        }        p = ptr;        MakePre(ptr->leftchild,p);        MakePre(ptr->rightchild,p);    }}void MakeThreadTreePre(BiThrNode *ptr){    BiThrNode *p = NULL;    MakePre(ptr,p);    p->rightchild = NULL;}

非递归中序线索化,需要两个函数,一个First函数一直左找,一个Next函数右找

BiThrNode *First(BiThrNode *p)    //一直往左找{    while(p != NULL && p->Ltag != Thread)    {        p = p->leftchild;    }    return p;}BiThrNode * Next(BiThrNode *p)    //右找{    if(p == NULL) return NULL;    if(p->Rtag == Thread)       {        return p->rightchild;    }else    {        return First(p->rightchild);    }}void ThrInOrder(BiThrNode *ptr)    //中序线索化{    for(BiThrNode *p =First(ptr); p != NULL; p = Next(p))    {        printf("%c ",p->data);    }    printf("\n");}

逆序打印中序线索化二叉树,和正序相似,需要两个函数,一个Last函数一直往右找,一个Prev找前继。

BiThrNode *Last(BiThrNode *p)   //一直往右找{    while(p!=NULL && p->Rtag !=Thread) //有标志指向得是右孩子    {        return p->rightchild;    }    return p;}BiThrNode *Prev(BiThrNode *p)  //找前继{    if(p == NULL) return NULL;    if(p->Ltag == Thread)    {        return p->leftchild;    }else    {        return Last(p->leftchild);    }}void ResInOrder(BiThrNode *ptr)   //逆序打印中序线索化二叉树{    for(BiThrNode *p =Last(ptr); p != NULL; p = Prev(p))    {        printf("%c ",p->data);    }    printf("\n");}
原创粉丝点击