线索二叉树如何是提升遍历速度的?线索二叉树有什么用?(以中序遍历为例)

很多人不知道线索二叉树利用了n+1个空指针是怎么加速遍历的,网上的课程都模模糊糊,不讲加速遍历的原理,只讲如何构建线索二叉树,下面我用自己搜集的一些资料,来解释线索二叉树如何遍历。

线索二叉树的构建无非就是有空的地方,指向某种遍历方式的前驱或后继,具体如何构建大家可以看其他文章,本文章仅仅解释线索二叉树如何提升遍历速度。

这是一个普通的二叉树:

二叉树根据中序遍历建立线索二叉树的图表如下:

黄色箭头就是原本为空的指针,现在指向了前驱与后继,可以看到H可以直接指向D、I可以指向B、E指向A、F指向C,而中序遍历的顺序就是HDIBEAFCG,可以说黄色箭头帮助一部分节点建立了指向关系。但是如果我们希望可以直接遍历下来,那么D就得指向I、B就得指向E、A指向F、c指向G,对于这部分我们是没有直接的箭头的,最明显的是A到F。

那么我们希望的是D可以直接找到I、B可以直接找到E这样的。另一篇文章给了我答案:

若 p->Rtag==0,说明有右子树,结点的后继是遍历右子树时第一个访问的结点(右子树中最左下结点)。

如果D的Rtag等于0,那么他是没有指向后继节点的,他只指向右子树的根节点,但是D结点的后继是右子树最左下角的结点,这句话很关键。

如图:

D的右子树的根节点是I,最左下角的结点也是I,

B的右子树的根节点是E,最左下角的结点也是E,

扫描二维码关注公众号,回复: 15495301 查看本文章

A的右子树的根节点是C,最左下角的结点是F,

C的右子树的根节点是G,最左下角的结点是G,

那么我们就可以发现如果Rtag==0,即指向右子树的根节点,那么我们可以通过寻找右子树最左下角的结点,这个结点是它的后继。

遍历代码Next如下:

TBNode *Next(TBNode *p)
{
    if (p->rtag==0) //表示有右孩子(右孩子不为空)
    {
        return First(p->rchild);
    }
    else
    {
        return p->rchild; //rtag==1,直接返回后继线索
    } 
}

TBNode *First(TBNode *p)
{
    while (p->ltag=0)//表示有左孩子(左孩子不为空)
    {
        return First(p->lchild);
    }
    return p;
}

如果Rtag==1,说明有直接的后继,Rtag==0;这里调用了First函数,函数的作用就是找到右子树最左下角的结点。

通过Next函数就可以依次向后遍历,向前遍历则同理。

猜你喜欢

转载自blog.csdn.net/weixin_55109830/article/details/129212902