c语言 扎扎实实的线索二叉树的遍历

看了网上不少线索二叉树的遍历流程代码:拿着严版教材一通copy就直接发到网上,关键的一些代码全都不说明。导致我自己琢磨好久

现在就把我琢磨的东西发出来分享!

那我来讲一下我学习的过程中看到这遇到的问题:

1.如何寻找当前节点的后继

2.如何确保中序线索遍历一直进行下去

下面我拿一个例子来进行讲解

我就拿我这个图来说,我先把他变成线索二叉树形态:

在编写代码的时候,首先就会思考第一个问题:如何寻找当前节点的下一个后继节点!比如说我要寻找9的后继,比如我要找7的后继节点,再比如我要找1的后继节点

首先解决第一个小问题:

寻找9的后继节点很简单:因为变成了线索树,只需要按照紫色箭头所指向的方向走下去即可:

反应到代码可以这么写:这个地方用到p->rtag就很简单了,只要p这个节点存在直接后继,我就让p走下去

if(p->rtag==1)
  q
=p->right;

第二个小问题:

如何找到7的后继:我们可以看到图中写到的中序遍历顺序是7到10,那么如何寻找呢?这里就需要总结出一个规律,当一个节点不能靠线索走下去的时候,那么他的后继就是其右孩子的最左边的子树,反应到图中就是7的孙子节点10,也就是9的左子树。

这里如果我们再变一下,假设10还存在n个左子树,那么7这个节点的后继就是10的最左边的那个孙子节点,反应到代码是这样的

        q=p->right;
        while(q->ltag==0)
            q=q->left;

代码的意思就是先将当前节点转化为其右节点,然后再沿其右节点一直往左子树的方向走

但是!注意我这里为什么没有直接写q=q->left;而是写为while条件语句!原因就和第三个小问题有关:

我们在寻找1这个节点的后继时发现,其右子树为3,当沿着3的左子树走下去的时候,发现3不存在左子树;3

就是1的直接后继。那么该怎么办呢?

可不可以将代码改成

while(q->left!=NULL)
    q=q->left;

答案是不行。

看上面我画的线索图,3有一条前驱指针指向1本身,如果按照上面的写法将会形成一个死循环1指向3,3指向1,无法出来。

所以我们这个地方一定要将while条件判断改成指向当前节点的“左孩子”,左孩子的判断很简单:当前节点的ltag=0的时候一定就有左孩子

你可能会问:

若q的左孩子是空怎么办?当前不会为空,之前线索化二叉树的时候已经将所有的空指针线索化了,tag==0就说明指针指向了孩子,tag==1就代表指针指向了前驱或者后继结点,不存在指针为空的情况。

那么我们的求节点后继的函数就可以这么写

Node* next(Node *p)
{
    Node *q=NULL;
    if(p->rtag==1)
        q=p->right;
    else
    {
        q=p->right;
        while(q->ltag==0)
            q=q->left;
    }
    return q;
}

写完了如何找到线索二叉树的后继,那么接下来就是如何遍历线索二叉树了:

我们值到中序二叉树的起点都是最左边的节点开始遍历,那么如何定位到最左边的节点呢?只需要用一个while循环:从根节点开始,不断遍历其左孩子,一直到rtag==1时,就说明不存在左孩子了,进而找到了我们需要的最左边的节点。

        while(p->ltag==0)
        {
            p=p->left;
        }
        printf("%d	",p->data);

这个地方printf出最左边节点的data,原因是最左边的孩子是中序遍历的第一个节点,自然需要打印出来

然后就只需要把线索二叉树当成一个链表,不断的往左走就可以了

        while(p->right!=NULL)
        {
            p=next(p);
            printf("%d	",p->data);
        }

 所以整个的代码可以写成这样

void RunInthread(Node *node)
{
    if(node==NULL)
        return;
    Node *p=node;
    if(p!=NULL)
    {
        while(p->ltag==0)
        {
            p=p->left;
        }
        printf("%d	",p->data);
        while(p->right!=NULL)
        {
            p=next(p);
            printf("%d	",p->data);
        }
        
    }
}
原文地址:https://www.cnblogs.com/oldfish123/p/12995718.html