5.4 二叉树的前驱和后继

转载:https://blog.csdn.net/xiaokang06/article/details/22092051

二叉树遍历的递归算法和非递归算法我们当然应该很熟悉了,不过还有另外一种遍
历方式,就是增加了树的构造,然后不允许递归或是用到栈进行遍历,如线索树或者是
有父母节点的二叉树等等等等。这样的遍历就需要我们找到一个节点的后继,同样如果
有更变态的题要求我们找一个节点的前驱,也和找后继是一个类型,下面我就关于三种
遍历方法的前驱和后继作一讨论和总结,让大家在考试的时候得心应手。也请高手给与
指正

一、前序遍历

1.1找后继:

        1、若有左子女,则后继是左子女;
        2、若无左子女,有右子女,则后继是右子女;
        3、若既无左子女,又无右子女,则是一片叶子;再讨论:
    a若是其父母的左子女,且父母有右子女,则后继是父母的右子女。
    b若是其父母的左子女,且父母无右子女;
    c若是其父母的右子女。
    b,c都表示这是某个节点的左子树前序遍历的最后一个节点,则需要找第一
个有右子树的“左祖先”(这个是我自己定义,即找第一个使得当前节点在这
个祖先的左子树上),然后后继就是这个祖先的右子女。
   如何找这个左祖先?即
   while((p->parent->rchildNULL||p->parent->rchildp)&&p!=NULL)
     p=p->parent;
   if(!p)表示已经全部遍历完毕。结束;else p=p->lchild;下一个节点

1.2找前驱

        1、若是父母的左孩子,则前驱是父母;
        2、若是父母的右孩子,且父母无左子树,则前驱是父母;
        3、若是父母的右孩子,父母有左子树,则前驱是父母左子树的最后访问到的节点
(指向父母的左子树后,一直往右,若不行的话,往左一步,一直到叶子)

二、中序遍历

2.1找后继

        1、如有右子女,后继是右子女的最左下节点;
        2、若无右子女,且是父母的左子女,则后继就是父母;
        3、若无右子女,且是父母的右子女,则一直上溯到第一个“左祖先”(定义如前
面)则后继就是这个祖先。若无这样的祖先,说明已经遍历完毕。

2.2找前驱

        1、如有左子女,前驱是左子女的最右下节点;
        2、若无左子女,且是父母的右子女,则前驱就是父母;
        3、若无左子女,且是父母的左子女,则一直上溯到第一个“右祖先”(定义如前
面)则前驱就是这个祖先。若无这样的祖先,说明已经遍历完毕。

三、后序遍历

3.1找后继

        1、若是父母的右孩子,则后继是父母;
        2、若是父母的左孩子,且父母无右子树,则后继是父母;
        3、若是父母的左孩子,父母有右子树,则后继是父母右子树的最先访问到的节点
(指向父母的右子树后,一直往左,若不行的话,往右一步,一直到叶子)

3.2找前驱:

        1、若有右子女,则前驱是右子女;
        2、若无右子女,有左子女,则前驱是左子女;
        3、若既无左子女,又无右子女,则是一片叶子;再讨论:
    a若是其父母的右子女,且父母有左子女,则前驱是父母的左子女。
    b若是其父母的右子女,且父母无左子女;
    c若是其父母的左子女。
    b,c都表示这是某个节点的右子树后序遍历的第一个节点,则需要找第一个
有左子树的“右祖先”,然后前驱就是这个祖先的左子女。
   其实前序遍历是“左右根”,中序遍历是“左根右”,后序是“左右根”,我们可
以看出,前序找后继和后序找前驱是对偶的(只要把左换成右,前驱换成后继,第一访
问换成最后访问即可),同样前序找前驱和后序找后继,中序找前驱和中序找后继都是
对偶的,这样记忆起来就非常方便了~~~~~

猜你喜欢

转载自blog.csdn.net/ZXG20000/article/details/113887429
5.4