线索二叉树
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
按照某种遍历方式对二叉树进行遍历时,可以把该二叉树中所有节点排列为一个线性序列。在该序列中,除第一个结点外,每个结点有且仅有一个直接前驱;除最后一个节点外,每个结点都有且仅有一个直接后继。但是,当以二叉链表作为存储结构时,只能得到结点的左右孩子的信息,而不能直接得到节点在某种遍历序列中的前驱和后继结点,这种信息只有在对二叉树遍历的动态过程中才能得到。
typedef struct ThBiNode
{
char data;
ThBiNode *lchild,*rchild;
int ltag,rtag;
}ThBiNode,*ThBiTree;
线索二叉树的基本操作
下面以中序线索二叉树为例。
1.建立中序线索二叉树
这也是对二叉树进行线索化的过程,即在遍历过程中,判断当前顶点的左右指针是否为空。若为空,则改为相应的前驱或者后继的线索。基本思路:设指针pre始终指向刚刚访问过的结点,即pre是当前访问结点的前驱。线索化过程中,访问p所指向的结点时,应作如下处理:
1)建立p的前驱线索。
若p->lchild为空,则将其左标志域置为1,并令p->lchild指向其中序前驱pre。
2)建立pre的后继线索。
若pre->rchild为空,则将其右标志域置为1,并令pre->rchild指向p。3)将pre指向p刚刚访问过的结点,即pre=p。这样,在p访问一个新结点时,pre为其前驱结点。
算法代码如下:
void InThreading(ThBiNode *p)
{
if(p)
{
InThreading(p->lchild);
if(!p->lchild)
{
p->lchild=pre;
p->ltag=1;
}
if(!pre->rchild)
{
pre->rchild=p;
pre->rtag=1;
}
pre=p;
InThreading(p->rchild);
}
}
2.在中序线索二叉树中查找任意结点的前驱结点
有两种情况:
1)如果该节点的左标志为1,那么其左指针所指向的就是它的前驱结点。2)如果该节点的左标志为0,即其左指针指向的是它的左孩子,此时它的前驱结点应该是遍历其左子树时最后访问的一个节点,即左子树中最右下的结点,从该节点的左子树出发沿右指针往下查找,当某节点的右标志为1时,它就是要找的前驱结点。
ThBiNode* FindPre(ThBiNode *p)
{
if(p->ltag==1)
return p->lchild;
else
{
p=p->lchild;
while(p&&!p->rtag)
p=p->rchild;
return p;
}
}
3.在中序线索二叉树中查找任意结点的后继结点。
两种情况:
1)如果该节点的右标志为1,那么其右指针域所指向的结点便是它的后继结点。
2)若果该节点的右标志为0,即其右指针指向它的右孩子,则它的后继结点是遍历其右子树时访问的第一个节点,也就是其右子树最左下结点。从该节点的右孩子开始,沿着左指针往下查找,当某节点的左标志为1,该节点即为目标节点。
ThBiNode* FindPost(ThBiNode *p)
{
if(p->rtag==1)
return p->rchild;
else
{
p=p->rchild;
while(p&&!p->ltag)
p=p->lchild;
return p;
}
}
4.线索二叉树的遍历。
在线索二叉树上进行遍历,只要找到序列中的第一个结点,然后依次找结点后继,直至其后继为空时为止。
若中序遍历线索二叉树,首先应该从根结点出发,沿左指针链不断往下查找,直到左指针为空,到达“最左下”结点,即中序遍历序列的第一个结点,然后反复找结点的中序后继即可。其实就等于是操作一个双向链表结构。和双向链表结构一样,在二叉树线索链表上添加一个头结点,并令其lchild域的指针指向二叉线索树的根节点,其rchild域的指针指向中序遍历时访问的最后一个节点。反之,令二叉线索树的中序序列中的第一个结点的lchild域指针和最后一个节点的rchild域指针均指向头结点。这样定义的好处是我们既可以从第一个节点起顺后继进行遍历,也可以从最后一个节点起顺前驱进行遍历。
#include
#include
typedef struct ThBiNode
{
char data;
struct ThBiNode *lchild,*rchild;
int ltag,rtag;
}ThBiNode,*ThBiTree;
void CreateThBiTree(ThBiTree&T)
{
char ch;
scanf("%c",&ch);
if(ch=='#')
T=NULL;
else
{
T=(ThBiTree)malloc(sizeof(ThBiNode)); T->data=ch;
T->ltag=0;
T->rtag=0;
CreateThBiTree(T->lchild);
CreateThBiTree(T->rchild);