二叉树的(先,中,后)序建树,线索化及遍历(四)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/weixin_39956356/article/details/80144113

后序线索化及遍历

注意:有些地方讲的粗超,是因为重复了,请看我的我的上篇文章。

(先序,中序)线索化及遍历(我的上篇文章):

https://blog.csdn.net/weixin_39956356/article/details/80142461

二叉树的(先,中,后)序的建树

https://blog.csdn.net/weixin_39956356/article/details/80141837

线索二叉树的基本知识:

https://blog.csdn.net/weixin_39956356/article/details/80141980
首先,不管在哪种线索化,都需要一个pre指针指向上次访问的结点,因为我们的目的是找到前驱和后继,那么就肯定需要两个指针(一前一后)。

一:后序线索化及遍历

递归与后序访问顺序

先序访问顺序

这里写图片描述

对应代码
//后序线索化
void PostThreading(BiThrTree p)
{
    if (p)
    {
        PostThreading(p->lchild);           //左子树线索化
        PostThreading(p->rchild);           //右子树线索化
        if (!p->lchild)                     //前驱线索
        {
            p->LTag = Thread;
            p->lchild = pre;
        }
        if (pre && !pre->rchild)            //后继线索
        {
            pre->RTag = Thread;
            pre->rchild = p;
        }
        pre = p;
        //visit(pre->data);
    }
}

3:后序线索化及遍历

这里没有在后序线索化添加虚设头结点!添加相对麻烦,不好处理。主要是由于它的线索化过程,要不断的的找双亲!!!

后序线索化遍历前驱与后继图
后序线索化及遍历

核心思想:递归,访问顺序,找双亲!!!

这里需要注意如果使用后序线索化就要用后序线索化遍历

这里写图片描述

对应代码
/********************************************************************
**  后序遍历--必须要后序线索化
**  后序遍历要使用带双亲的三叉链表
********************************************************************/
Status PostOrderTraverse(BiThrTree T, Status(*visit)(TElemType e))
{
    if (T)
    {
        BiThrTree p = T;
        pre = NULL;                                                     //由于使用了同一个pre全局变量,在后序线索化pre值会遗留成根节点,这里要排除
        while (pre != T)
        { 
            while (p->LTag == Link)                 //第一步:找树最左边的节点 
            {
                p = p->lchild;
            }
            while (p && p->RTag == Thread)                              //261行
            {
                visit(p->data);
                pre = p;                                                //这里用一个pre来记录,看似和线索化相重复,实际上并不是,在遍历的时候需要获取双亲节点,要有pre
                p = p->rchild;
            }
            while (pre != T && p->rchild == pre)                        //pre始终在p的后面,如果pre都指向根节点,那么久不需要找双亲,同时也是遍历结束的标志
            {
                visit(p->data);
                pre = p;
                if(pre != T)
                    p = p->Parent;                                      //找双亲
            }
            if (p->RTag == Link)                                        //重复261行,相当于又从新节点往左走                            
            {
                p = p->rchild;
            }
        }
    }
    return OK;
}
先序线索化及遍历输出结果

这里写图片描述

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

main代码

注意:三种线索化每次只能使用一种,否则会出现死循环
#include "stdafx.h"
#include "thread.h"

/********************************************************************
**  TParent     :双亲节点(后序线索化)
**  BiThrRoot   :头结点(先,中序线索化)
**  T           :根节点
********************************************************************/

int main()
{
    //先序数组
    char Vexch[26] = { 'A','B','D','H','$','$','I','$','$','E','J','$','$','$','C','F','$','$','G','$','$' };

    BiThrTree T, TParent, BiThrRoot;                                
    printf("先序创建二叉树\n");
    CreatPreBiThreadTree(T, Vexch);
    printf("\n");

    printf("中序创建二叉树\n");
    CreatInBiThreadTree(T, Vexch);
    printf("\n");

    printf("后序创建二叉树\n");
    CreatPostBiThreadTree(T, Vexch, TParent);
    printf("\n");

//注意:以下三段只能一次只能使用其中一组,不同线索化会覆盖之前的线索化,从而出现死循环
    //printf("\n先序遍历线索二叉树\n");
    //PreOrderThreading(BiThrRoot, T);
    //PreOrderTraverse(BiThrRoot, visit);
    //printf("\n");

    //printf("\n中序遍历线索二叉树\n");
    //InOrderThreading(BiThrRoot, T);
    //InOrderTraverse(BiThrRoot, visit);
    //printf("\n");

    printf("\n后序遍历线索二叉树\n");
    PostThreading(T);
    PostOrderTraverse(T, visit);
    printf("\n");


    printf("\n");
    return 0;
}

最后在此感谢以下博主文档的启发与参考

https://blog.csdn.net/my_heart_/article/details/52086321
https://blog.csdn.net/qq_34328833/article/details/52764437
https://blog.csdn.net/DouBoomFly/article/details/71572601
https://www.cnblogs.com/chengsong/p/5069454.html

整个程序压缩包百度云链接(我的是VS2017哦,VS仅仅向下兼容):

链接: https://pan.baidu.com/s/1nB6Li7kUBsHGVcfuusyL6A 密码: bt5i

如有疑问,可以加qq:2102388688,务必备注“二叉树线索化及遍历问题”

转载请提及转载链接,谢谢!!!

猜你喜欢

转载自blog.csdn.net/weixin_39956356/article/details/80144113