更新:
为了让文章篇幅不太长,我将指针的引用部分另外写成了一篇文章。
如果有需要,还请自行踱步。Nice小夫:#图解 轻松看懂指针的引用*&zhuanlan.zhihu.com
什么是线索二叉树?
线索二叉树分为三类:
对一棵二叉树中所有节点的空指针域按照某种遍历方式加线索的过程叫作线索化,被线索化了的二叉树称为线索二叉树。
为什么需要线索二叉树?
知道了“前驱”和“后继”信息,就可以把二叉树看作一个链表结构,从而可以像遍历链表那样来遍历二叉树,进而提高效率。
如何线索化二叉树
这里例举了中序线索二叉树的方法
一个二叉树通过如下的方法“串起来”:
所有原本为空的右(孩子)指针改为指向该节点在中序序列中的后继,所有原本为空的左(孩子)指针改为指向该节点的中序序列的前驱。
这句话我是借鉴了了另一位知友的总结,可以说是一看就懂了。
但我并不满足于此,我要让这句话更加直观展现出来。
我这个图这样直观展示,是有意为之的。
让你看到左孩子空,就会想到直接前驱。右孩子空,就会想到直接后继。
线索二叉树的结构线索二叉树节点结构
标识域:如果ltag=0,表示指向节点的左孩子。如果ltag=1,则表示lchild为线索,指向节点的直接前驱
如果rtag=0,表示指向节点的右孩子。如果rtag=1,则表示rchild为线索,指向节点的直接后继
什么是前驱后继,不需要我解释了吧。
所以对应的线索二叉树的节点定义如下:
typedef struct TBNode
{
char data;
int ltag,rtag;
struct TBNode *lchild;
struct TBNode *rchild;
}TBNode;中序线索二叉树二叉链表表示
我们心目中的代码就是要将中序线索二叉树用二叉链表来实现。
我们来一步一步的书写代码:
约定:指针p指向当前正在访问的节点
pre指向p的前驱节点
// 通过中序遍历对二叉树线索化的递归算法:void InThread(TBNode *p,TBNode *&pre)
{
if (p!=NULL)
{
InThread(p->lchild,pre); //递归,左子树线索化}
if (p->lchild==NULL)
{
p->lchild=pre;
p->ltag=1;
}
if (pre!=NULL&&pre->rchild==NULL)
{
//建立前驱节点的后继线索pre->rchild=p;
pre->rtag=1;
}
pre=p; //pre指向当前的p,作为p将要指向的下一个节点的前驱节点提示指针
InThread(p->rchild,pre);
}
通过中遍历建立中序线索二叉树的主要程序
// 通过中遍历建立中序线索二叉树的主要程序void createInThread(TBNode *root)
{
TBNode *pre=NULL; //前驱节点指针if (root!=NULL)
{
InThread(root,pre);
pre->rchild=NULL;//非空二叉树线索化pre->rtag=1; //处理中序最后一个节点}
}
遍历中序线索二叉树
求以p为根的中序线索二叉树中,中序序列下的第一个节点。
TBNode *First(TBNode *p)
{
while (p->ltag=0)//表示有左孩子(左孩子不为空){
return First(p->rchild);
}
return p;
}
求在中序线索二叉树中,节点p在中序下的后继节点。
TBNode *Next(TBNode *p)
{
if (p->rtag==0) //表示有右孩子(右孩子不为空){
return First(p->rchild);
}
else
{
return p->rchild; //rtag==1,直接返回后继线索}
}
中序线索二叉树上执行中序遍历的算法
void Inorder(TBNode *root)
{
for (TBNode *p=First(root) ; p!=NULL ; p=Next(p))
{
Visit(p); //Visit()是已经定义的访问p所指节点的函数}
}
剩下的前序线索二叉树遍历和后序线索二叉树,套路还不是一样一样的?
我的更多图解教程:Nice小夫:#图解 数据结构:树的存储结构zhuanlan.zhihu.comNice小夫:#图解 数据结构:树和森林与二叉树的相互转换zhuanlan.zhihu.comNice小夫:#图解+动画 数据结构-循环链表:约瑟夫环问题(C语言实现)zhuanlan.zhihu.comNice小夫:#动画 算法初步:选择排序。过于简单!zhuanlan.zhihu.comNice小夫:#图解 必胜之策!生活中的博弈论:抓三堆问题。这四张图让你懂得一塌糊涂zhuanlan.zhihu.comNice小夫:#图解+动画 不败法则!生活中的博弈论:简简单单躺赢。一张图让你彻彻底底搞明白!zhuanlan.zhihu.comNice小夫:#图解 考研英语语法:状语从句zhuanlan.zhihu.comNice小夫:#图解 考研英语语法:名词性从句zhuanlan.zhihu.com
Nice!Nice!Nice!
明白啦。