目的:
利用链表存储二叉树,其中能够表示出中序遍历二叉树时节点的前驱和后继信息
而当结点的左右子树存在时,其前驱和后继就分别是左孩子,右孩子。
故只需要给左右子树为空的节点加信息就好啦
那就共用左右孩子lchild ,rchild指针,附加一个标志tag来表示其lchid,rchild指向的是左孩子右孩子,还是前驱和后继
链表的数据结构
typedef struct BiThrNode
{
char data;
struct BiThrNode *lchild,*rchild;
int LTag,RTag;
}BiThrNode,*BiThrTree;
下面就是将其线索化了
而我们要给出其遍历时的前驱和后继,那就得自己先走一遍,边走边放线索不是?
所以算法最基本框架是中序遍历
void InThreading(BiThrTree p)
{
if(p)
{
InThreading(p->lchild);
cout<<p->data;
InThreading(p->rchild);
}
}
而对于我们要遍历的每个节点,得知道它的前驱和后继,一个节点来遍历肯定不够啊
所以用两个节点
一个在前, pre 表示p可能的前驱
一个在后,p p是pre可能的后继
初始时,pre为NULL p为根节点
当p递归到它左孩子不存在时,pre就排上用场了,p->lchild=pre Tag置为1
当pre的右节点不存在时,p就派上用场 pre->rchild=p Tag置为1
然后p一步步遍历,pre跟在它后面,每次判断一下p的左节点是否存在,pre的右节点是否存在
存在的话就老老实实指向左右孩子,不存在就动用前驱后继
利用线索进行遍历
1.找到第一个节点
2.输出该节点,然后一直找它后继,输出
3.后继不存在时就说明该节点它的右节点存在,访问右节点
由于我们已经知道了后继信息,遍历时就让它自己跟着后继一步一步来就行了
后继信息
完整代码
#include<iostream>
using namespace std;
typedef struct BiThrNode
{
char data;
struct BiThrNode *lchild,*rchild;
int LTag,RTag;
}BiThrNode,*BiThrTree;
BiThrNode *pre=new BiThrNode;
void CreateBiTree(BiThrTree &T)
{
char ch;
cin >> ch;
if(ch=='#') T=NULL;
else
{
T=new BiThrNode;
T->data=ch;
CreateBiTree(T->lchild);
CreateBiTree(T->rchild);
}
}
void InThreading(BiThrTree p)
{
if(p)
{
InThreading(p->lchild);
if(!p->lchild)
{
p->LTag=1;
p->lchild=pre;
;
}
else
p->LTag=0;
if(!pre->rchild)
{
pre->RTag=1;
pre->Rchild=p;
}
else
pre->RTag=0;
pre=p;
;
InThreading(p->rchild);
}
}
void InOrderTraverse_Thr(BiThrTree T)
{
BiThrTree p;
p=T;
while(p)
{
while(p->LTag==0)
p=p->lchild;
cout<<p->data;
while(p->RTag==1)
{
p=p->rchild;
cout<<p->data;
}
p=p->rchild;
}
}
int main()
{
pre->RTag=1;
pre->rchild=NULL;
BiThrTree tree;
CreateBiTree(tree);
InThreading(tree);
InOrderTraverse_Thr(tree);
return 0;
}
小白第一次写博客,水平问题定有疏漏,如有错误恳请指正