一、线索二叉树的构造
#include <stdio.h>
//定义线索二叉树结点
typedef struct ThreadNode
{
int data; //数据域存放二叉树数据
ThreadNode * lchild,*rchild; //左右孩子
int ltag,rtag; //左右孩子标志位
}ThreadNode,* ThreadTree;
ThreadNode * pre; //全局变量,当前结点的前驱结点二、构造并中序线索化
//访问某一个树结点同时进行线索化
void Visit(ThreadNode * p)
{
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置为当前结点,当下一次调用visit时访问的pre就是当前结点(下一次遍历的前驱)
}
//二叉树中序遍历(并调用Visit进行线索化)
void InThread(ThreadTree T)
{
if(T!=NULL)
{
InThread(T->lchild);
Visit(T);
InThread(T->rchild);
}
}
void CreateInThread(ThreadTree T)
{
pre=NULL;
if(T!=NULL)
{
InThread(T);
if(pre->rchild==NULL) pre->rtag=1; //对最后一个结点进行特殊处理
}
}三、构造并先序线索化(构造代码同上)
//二叉树先序遍历(并调用Visit进行线索化)
void InThread(ThreadTree T)
{
if(T!=NULL)
{
Visit(T);
if(T->LTag==0)InThread(T->lchild); //!!!注意此处的判断条件,因为先序遍历访问顺序是根左右,如果根线索化了,无论根有没有左孩子,lchild都有指向,因此必须加此判断条件,判断其到底有没有左孩子
InThread(T->rchild);
}
}四、线索二叉树的遍历
(1)中序遍历
//找到以p为根的子树中第一个被中序遍历的结点,即最左下的那个结点
ThreadNode * FirstNode(ThreadNode * p)
{
while(p->ltag==0) p=p->lchild;
return p;
}
//找到某个结点的后继节点
ThreadNode * NextNode(ThreadNode * p)
{
if(p->rtag==1) return p->rchild;
else if(p->rchild==0) return FirstNode(p->rchild); //返回右子树最左下的那个结点
}
void Inorder(ThreadTree * T)
{
for(ThreadNode * p=FirstNode(T);p!=NULL;p=NextNode(p)) //先找到第一个结点,然后不断的找其后继
visit(p);
}(2)逆向中序遍历:从最后一个结点开始不断遍历其前驱即可。

京公网安备 11010502036488号