二叉树的线索化

为什么要线索化二叉树?
:传统的二叉树的链式存储,只能体现一种父子关系,不能直接得到结点在遍历中的前驱结点和后继结点,而且一般仅能从最上方往下找,很不方便,不能从任意结点开始遍历寻找前驱后继。前文中提过二叉树链式存储有n+1个空链域,所以可以充分利用这n+1个空指针构造出线索二叉树使得我们更方便的遍历二叉树。

//不线索化找前驱
typedef struct BTNode
{
    int data;
    struct BTNode *lchild,*rchild;
}BTNode,*BTree;

//查找结点p的前驱
BTree *p;//p指向目标结点
BTree *pre=nullptr;//前驱结点
BTree *final=nullptr;//记录最终的结点

void visit(BTree *q)
{
    if (q==p)
    {
        final=pre;//找到p的前驱结点
    }
    else
    {
        pre=q; //pre指向当前访问的结点
    }
    
    
}

void FindPre(BTree T)
{
    if (T)
    {
        FindPre(T->lchild);
        visit(&T);
        FindPre(T->rchild);
    }
    
}


//线索二叉树:
typedef struct ThreadNode
{
    int data;
    struct ThreadNode *lchild,*rchild;
    int ltag,rtag;
}ThreadNode,*ThreadTree;

ThreadNode *pr=nullptr;//全局变量:前驱,之后三种线索化公用。

void visit(ThreadNode *T)
{
    if (T->lchild==nullptr)
    {
        T->lchild=pr;
        T->ltag=1;
    }
    if (pr&&T->rchild==nullptr)
    {
        pr->rchild=T;//建立前驱结点的后继指针
        pr->ltag=1;
    }
    pr=T;
    //最后特别处理pr,因为pr遍历到最后一个结点时,
    //若右节点为空,则pr的tag应为1,所以可以利用pr是全局变量在别的函数进行判断修改
}

//中序遍历线索化:
void InThread(ThreadTree T)
{
    if (T)
    {
        InThread(T->lchild);
        visit(T);
        InThread(T->rchild);
    }
    
}

void CreateInThread(ThreadTree T)
{
    pr=nullptr;//pr初始为NULL
    if (T)//非空二叉树才能线索化
    {
        InThread(T);
        if (pr->rchild==nullptr)
        {
            pr->rtag=1;//处理遍历的最后一个结点的tag值
        }
        
    }
    
}


//先序线索化:
void PreThread(ThreadTree T)
{
    if (T)
    {
        visit(T);//先处理根节点
        if(T->ltag==0)//lchild不是前驱线索,防止死循环
            PreThread(T->lchild);
        PreThread(T->rchild);
    }
    
}
void CreatePreThread(ThreadTree T)
{
    pr=nullptr;
    if (T)
    {
        PreThread(T);
        if (pr->rchild==nullptr)
        {
            pr->rtag=1;
        }
        
    }
    
}

//后序线索化:
void PostThread(ThreadTree T)
{
    if (T)
    {
        PostThread(T->lchild);
        PostThread(T->rchild);
        visit(T);
    }
    
}
void CreatePostThread(ThreadTree T)
{
    pr=nullptr;
    if (T)
    {
        PostThread(T);
        if (pr->rchild==nullptr)//处理最后一个结点
        {
            pr->rtag=1;
        }
        
    }
    
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值