版权声明:本文为博主原创文章,未经博主允许不得转载。 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