初学数据结构(中序线索化二叉树)

初学数据结构(中序线索化二叉树)

《数据结构教程》P243 exp7-4

交作业版

//
// Created by Snow on 2023/4/5.
//
#include<cstdio>
#include<cstdlib>
#define MaxSize 50
typedef char ElemType;
typedef struct node
{
    ElemType data;
    int ltag,rtag;
    struct node *lchild;
    struct node *rchild;
}TBTNode;
void CreateTBTree(TBTNode *&b,const char *str)
{
    TBTNode *St[MaxSize],*p=nullptr;
    int top=-1,k,j=0;
    char ch;
    b=nullptr;
    ch=str[j];
    while(ch!='\0')
    {
        switch(ch)
        {
            case '(':top++;St[top]=p;k=1;break;
            case ')':top--;break;
            case ',':k=2;break;
            default:
                p=(TBTNode*)malloc(sizeof(TBTNode));
                p->data=ch;
                p->lchild=p->rchild=nullptr;
                if(b==nullptr)
                    b=p;
                else
                {
                    switch(k)
                    {
                        case 1:St[top]->lchild=p;break;
                        case 2:St[top]->rchild=p;break;
                    }
                }
        }
        j++;
        ch=str[j];
    }
}
void DispTBTree(TBTNode *b)
{
    if(b!=nullptr)
    {
        printf("%c",b->data);
        if(b->lchild!=nullptr||b->rchild!=nullptr)
        {
            printf("(");
            DispTBTree(b->lchild);
            if(b->rchild!=nullptr)printf(",");
            DispTBTree(b->rchild);
            printf(")");
        }
    }
}
TBTNode *pre;
void Thread(TBTNode *&p)
{
    if(p!=nullptr)
    {
        Thread(p->lchild);
        if(p->lchild==nullptr)
        {
            p->lchild=pre;
            p->ltag=1;
        }
        else
        {
            p->ltag=0;
        }
        if(pre->rchild==nullptr)
        {
            pre->rchild=p;
            pre->rtag=1;
        }
        else
        {
            pre->rtag=0;
        }
        pre=p;
        Thread(p->rchild);
    }
}
TBTNode *CreateThread(TBTNode *b)
{
    TBTNode *root;
    root=(TBTNode*)malloc(sizeof(TBTNode));
    root->ltag=0;
    root->rtag=1;
    root->rchild=b;
    if(b==nullptr)
        root->lchild=root;
    else
    {
        root->lchild=b;
        pre=root;
        Thread(b);
        pre->rchild=root;
        pre->rtag=1;
        root->rchild=pre;
    }
    return root;
}
void ThInOrder(TBTNode *tb)
{
    TBTNode *p=tb->lchild;
    while(p!=tb)
    {
        while(p->ltag==0)
            p=p->lchild;
        printf("%c",p->data);
        while(p->rtag==1&&p->rchild!=tb)
        {
            p=p->rchild;
            printf("%c",p->data);
        }
        p=p->rchild;
    }
}
void DestroyTBTree1(TBTNode *&b)
{
    if(b->ltag==0)
        DestroyTBTree1(b->lchild);
    if(b->rtag==0)
        DestroyTBTree1(b->rchild);
    free(b);
}
void DestroyTBTree(TBTNode *&tb)
{
    DestroyTBTree1(tb->lchild);
    free(tb);
}
void Disp(TBTNode *b)
{
    if(b==nullptr)
        return;
    if(b->ltag==0)
        Disp(b->lchild);
    printf("%c",b->data);
    if(b->rtag==0)
        Disp(b->rchild);
}
int main()
{
    TBTNode *b,*tb;
    CreateTBTree(b,"A(B(D,E(H(J,K(L,M(,N))))),C(F,G(,I)))");
    DispTBTree(b);
    printf("\n构造中序线索化二叉树\n");
    tb=CreateThread(b);
    printf("非递归输出:");
    ThInOrder(tb);
    printf("\n");
    printf("递归输出:");
    Disp(tb->lchild);
    printf("\n销毁线索二叉树\n");
    DestroyTBTree(tb);
    return 1;
}

注释版

//
// Created by Snow on 2023/4/3.
//
#include<cstdio>
#include<cstdlib>
#define MaxSize 50
typedef char ElemType;
typedef struct node
{
    ElemType data;
    int ltag,rtag;//增加的线索标记,值为0表示lchild(rchild)指向左(右)孩子结点,为1表示指向前驱(后继)结点
    struct node *lchild;
    struct node *rchild;
}TBTNode;
void CreateTBTree(TBTNode *&b,const char *str)
{
    TBTNode *St[MaxSize],*p=nullptr;
    int top=-1,k,j=0;
    char ch;
    b=nullptr;				//建立的二叉树初始时为空
    ch=str[j];
    while (ch!='\0')	//str未扫描完时循环
    {
        switch(ch)
        {
            case '(':top++;St[top]=p;k=1;break;		//为左节点
            case ')':top--;break;
            case ',':k=2; break;                      	//为右节点
            default:
                p=(TBTNode *)malloc(sizeof(TBTNode));
                p->data=ch;
                p->lchild=p->rchild=nullptr;
                if (b==nullptr)					//*p为二叉树的根节点
                    b=p;
                else  							//已建立二叉树根节点
                {
                    switch(k)
                    {
                        case 1:St[top]->lchild=p;break;
                        case 2:St[top]->rchild=p;break;
                    }
                }
        }
        j++;
        ch=str[j];
    }
}
void DispTBTree(TBTNode *b)
{
    if (b!=nullptr)
    {
        printf("%c",b->data);
        if (b->lchild!=nullptr || b->rchild!=nullptr)
        {
            printf("(");
            DispTBTree(b->lchild);
            if (b->rchild!=nullptr) printf(",");
            DispTBTree(b->rchild);
            printf(")");
        }
    }
}
//中序线索二叉树
TBTNode *pre;//全局变量
void Thread(TBTNode *&p)//对二叉树p进行中序线索化
{
    if(p!=nullptr)
    {
        Thread(p->lchild);//左子树线索化
        if(p->lchild==nullptr)//左孩子不存在,进行前驱结点线索化
        {
            p->lchild=pre;//建立当前结点的前驱结点线索
            p->ltag=1;
        }
        else//p结点的左子树已线索化
        {
            p->ltag=0;
        }
        if(pre->rchild==nullptr)//对pre的后继结点线索化
        {
            pre->rchild=p;//建立前驱结点的后继结点线索
            pre->rtag=1;
        }
        else
        {
            pre->rtag=0;
        }
        pre=p;
        Thread(p->rchild);//右子树线索化
    }
}
TBTNode *CreateThread(TBTNode *b)//中序线索化二叉树
{
    TBTNode *root;
    root=(TBTNode*)malloc(sizeof(TBTNode));//创建头结点
    root->ltag=0;
    root->rtag=1;
    root->rchild=b;
    if(b==nullptr)//空二叉树
        root->lchild=root;
    else
    {
        root->lchild=b;
        pre=root;//pre是结点p的前驱结点,供加线索用
        Thread(b);//中序遍历线索化二叉树
        pre->rchild=root;//最后处理,加入指向头结点的线索
        pre->rtag=1;
        root->rchild=pre;//头结点右线索化
    }
    return root;
}
void ThInOrder(TBTNode *tb)//tb指向中序线索二叉树的头结点
{
    TBTNode *p=tb->lchild;//p指向根节点
    while(p!=tb)
    {
        while(p->ltag==0)//找开始结点
            p=p->lchild;//访问开始结点
        printf("%c ",p->data);
        while(p->rtag==1&&p->rchild!=tb)
        {
            p=p->rchild;
            printf("%c ",p->data);
        }
        p=p->rchild;
    }
}
//递归遍历中序线索树
void InOrder(TBTNode *b)
{
    if(b==nullptr) //如果当前结点为空,直接返回
        return;
    if(b->ltag==0)//如果当前结点的左标志域为0,表示有左孩子,递归调用函数处理左孩子
        InOrder(b->lchild);
    printf("%c",b->data);//输出当前结点的值
    if(b->rtag==0)//如果当前结点的右标志域为0,表示有右孩子,递归调用函数处理右孩子
        InOrder(b->rchild);
}
void DestroyTBTree1(TBTNode *&b)	//销毁
{	if (b->ltag==0)					//节点b有左孩子,释放左子树
        DestroyTBTree1(b->lchild);
    if (b->rtag==0)					//节点b有右孩子,释放右子树
        DestroyTBTree1(b->rchild);
    free(b);
}
void DestroyTBTree(TBTNode *&tb)	//销毁一棵带头结点的中序线索树tb
{
    DestroyTBTree1(tb->lchild);		//释放以tb->lchild为根节点的树
    free(tb);						//释放头节点
}
int main()
{
    TBTNode *b,*tb;
    CreateTBTree(b,"A(B(D(,G)),C(E,F))");
    DispTBTree(b);printf("\n");
    tb=CreateThread(b);
    ThInOrder(tb);printf("\n");
    DestroyTBTree(tb);
    return 1;
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值