第六章 树和二叉树 (二)

@第六章 树和二叉树 (二)

  • 线索二叉树(要求掌握中序遍历的代码)
  • 树和森林与二叉树的相互转换(要求掌握转换方法)
  • 赫夫曼树和赫夫曼编码(要求掌握构建方法)

线索二叉树参考链接
https://blog.csdn.net/qq_39295755/article/details/79535406

typedef struct TBTNode
{
    char data;
    int ltag,rtag; //线索标记
    struct TBTNode *lchild;
    struct TBTNode *rchild;
}TBTNode;

//通过中序遍历对二叉树线索化的递归算法
void InThread(TBTNode *p,TBTNode *&pre)
{
    if(p!=NULL)  //p指向当前结点 pre指向p的前驱结点
    {
        InThread(p->lchild,pre); //递归,左子树线索化
        if(p->lchild==NULL) 
        {                       //建立当前结点的前驱线索
            p->lchild=pre;
            p->ltag=1;
        }
        if(pre!=NULL && pre->rchild==NULL) 
        {                   //建立当前结点的后继线索
            pre->rchild=p;
            pre->rtag=1;
        }
        pre=p;     //pre指向当前的p,作为p要指向的下一个结点的前驱结点指示指针
        InThread(p->rchild,pre);

        /*  p=p->rchild;//p指向一个新结点,此时pre和p分别指向的结点形成了一个前驱后继为下一次线索的连接做准备
        InThread(p,pre); //递归,右子树线索化  */
    }
}
//通过中序遍历建立中序线索二叉树的主程序
void createInThread(TBTNode *root)
{
    TBTNode *pre=NULL; //前驱结点指针
    if(root!=NULL)
    {
        InThread(root,pre);
        pre->rchild=NULL; //非空二叉树,线索化后处理中序最后一个结点
        pre->rtag=1;    
    }
}
//在以p为根的中序线索二叉树中,中序序列下的第一个结点算法
TBTNode *First(TBTNode *p)
{
    while(p->ltag==0)
        p=p->lchild; //最左下结点(不一定时叶结点)
    return p;
}
//在求中序线索二叉树中,结点p在中序下的后继结点
TBTNode *Next(TBTNode *p)
{
    if(p->rtag==0)
        return First(p->rchild);
    else
        return p->rchild;
}
//中序线索二叉树上执行中序遍历算法
void Inorder(TBTNode *root)
{
    for(TBTNode *p=First(root);p!=NULL;p=Next(p))
        Visit(p);//Visit()是已经定义的访问p所指结点的函数
}
前序线索二叉树及后序线索二叉树
//前序线索二叉树
void preThread(TBTNode *p,TBTNode *&pre)
{
    if(p!=NULL)
    {
        if(p->lchild=NULL)
        {
            p->lchild=pre;
            p->ltag=1;
        }
        if(pre!=NULL&&pre->rchild==NULL)
        {
            pre->rchild=p;
            pre->rtag=1;
        }
        pre=p;
        //在递归入口处有限制条件,左右指针不是线索才能继续递归
        if(p->ltag==0)
            preThread(p->lchild,pre);
        if(p->rtag==0)
            preThread(p->rchild,pre);
    }
}
void preorder(TBTNode *root)
{
    if(root!=NULL)
    {
        TBTNode *p=root;
        while(p!=NULL)
        {
            while(p->ltag==0) 
            {
                Visit(p);
                p=p->lchild;
            }
            Visit(p);
            p=p->rchild; 
        }
    }
}
//后序线索二叉树
void postThread(TBTNode *p,TBTNode *&pre)
{
    if(p!=NULL)
    {
        postThread(p->lchild,pre);
        postThread(p->rchild,pre);
        if(p->lchild==NULL)
        {
            p->lchild=pre;
            p->ltag=1;
        }
        if(pre!=NULL && pre->rchild==NULL)
        {
            pre->rchild=p;
            pre->rtag=1;
        }
        pre=p;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值