中序线索二叉树的构造和中序遍历
中序线索二叉树的构造
何为线索二叉树?
lchild | ltag | data | rtag | rchild |
---|
把n个结点二叉树中的n+1个空指针域利用起来,可以得到几种遍历序列的直接前驱和直接后继。
线索二叉树的存储结构:
typedef struct ThreadNode
{
int data;
struct ThreadNode *lchild,*rchild;
int ltag,rtag;
}ThreadNode,*ThreadTree;
中序线索二叉树的遍历
建立一个中序线索二叉树就是将二叉树中序遍历一次,而后把二叉链表中的空指针改为指向其直接前驱或者直接后继的线索。
用中序遍历对二叉线索树的递归算法:
//通过中序遍历对二叉树线索化的递归算法
void InThread(ThreadTree &p,ThreadTree &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
InThread(p->rchild,pre); //递归,线索化右子树
}
}
void CreateInThread(ThreadTree T)
{
ThreadTree pre=NULL;
if(T!=NULL) //非空二叉树,线索化
{
InThread(T,pre); //线索化二叉树
pre->rchild=NULL; //处理最后一个结点
pre->rtag=1; //做标记
}
}
中序线索二叉树的遍历:
ThreadNode* Firstnode(ThreadNode *p) //找第一个结点
{
while(p->ltag==0)
p=p->lchild;
return p;
}
ThreadNode* Nextnode(ThreadNode *p)
{
if(p->rtag==0)
return Firstnode(p->rchild);
else
return p->rchild; //rtag==1就直接返回后继线索
}
void InThreadOrder(ThreadNode *T)
{
for(ThreadNode *p=Firstnode(T);p!=NULL;p=Nextnode(p))
{
cout<<p->data<<" ";
}
}
如何构造线索二叉树就省略了,在数据结构复习(一)里有类似的,就是多两个变量。
最后的实现:
int main()
{
//5 3 4 8 7 9
int a[6];
int i=0;
cout<<"输入6位数:"<<endl;
for(i=0;i<6;i++)
{
cin>>a[i];
}
for(i=0;i<6;i++)
{
// AddBTNode(a[i]);
AddIndexBTNode(a[i]);
}
CreateInThread(tTree);
cout<<"中序遍历线索二叉树:"<<endl;
InThreadOrder(tTree);
cout<<endl;
return 0;
}
实现结果: