zoukankan      html  css  js  c++  java
  • 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);
            }
            
        }
    }
  • 相关阅读:
    不务正业系列-浅谈《过气堡垒》,一个RTS玩家的视角
    [LeetCode] 54. Spiral Matrix
    [LeetCode] 40. Combination Sum II
    138. Copy List with Random Pointer
    310. Minimum Height Trees
    4. Median of Two Sorted Arrays
    153. Find Minimum in Rotated Sorted Array
    33. Search in Rotated Sorted Array
    35. Search Insert Position
    278. First Bad Version
  • 原文地址:https://www.cnblogs.com/oldfish123/p/12995718.html
Copyright © 2011-2022 走看看