您的位置:首页 > 其它

二叉树的线索化

2015-10-28 14:42 239 查看
惯例:菜鸟一枚,如有错误和不妥之处请各位大神多多指出,谢谢!

二叉树的传统链式存储结构仅能体现出一种节点的父子关系,不能直接得到节点在遍历中的前驱和后继。由于二叉链表中存在大量的空指针,可以利用这些空指针存放节点的前驱和后继,这样子就可以方便地进行二叉树的有关其它操作算法。因此,线索二叉树目的是加快查找节点的前驱和后继的速度。

二叉树线索化时规定:若节点无左子树,令其lchild指向其前驱;若节点无右子树,令其rchild指向其后继。同时,每个节点需要增加两个标志域(ltag和rtag)表明当前的指针域所指的对象是左(右)子节点还是直接前驱(后继)。通常标志域定义如下:

ltag: 左孩子时为0,前驱时为1.

rtag: 右孩子时为0,后继时为1.

以下代码为对二叉树中序线索化的构造,然后对中序线索化后的二叉树进行中序遍历。代码及测试结果截图如下:

#include<iostream>
using namespace std;
typedef struct BiTNode{
char data;
struct BiTNode *lchild,*rchild;
int ltag,rtag;
}BiNode,*BiTree;

void creatBiTree(BiTree &T){
char x;
scanf("%c",&x);
if(x=='#'){
T=NULL;
}
else{
T=(BiTree)malloc(sizeof(BiNode));
T->data=x;
T->ltag=0;
T->rtag=0;
creatBiTree(T->lchild);
creatBiTree(T->rchild);
}
}
void Visit(BiTree T){//访问树节点元素
if(T!=NULL){
printf("%3c",T->data);
}
}
void InThread(BiTree &T,BiTree &pre){//通过中序遍历对二叉树线索化
if(T!=NULL){
InThread(T->lchild,pre);
if(T->lchild==NULL){
T->lchild=pre;
T->ltag=1;
}
if(pre!=NULL && pre->rchild==NULL){
pre->rchild=T;
pre->rtag=1;
}
pre=T;
InThread(T->rchild,pre);
}
}
void CreatInThread(BiTree T){//中序遍历建立中序线索二叉树
BiTree pre=NULL;
if(T!=NULL){
InThread(T,pre);
pre->rchild=NULL;
pre->rtag=1;
}
}
BiTree Firstnode(BiTree p){//求中序线索二叉树中中序遍历的第一个节点
while(p->ltag==0)
p=p->lchild;
return p;
}
BiTree Nextnode(BiTree p){//求中序线索二叉树中节点P在中序序列下的后继节点
if(p->rtag==0)
return Firstnode(p->rchild);
else
return p->rchild;
}
void InOrder(BiTree T){//遍历
for(BiTree p=Firstnode(T);p!=NULL;p=Nextnode(p))
Visit(p);
}
int main(){
BiTree T;
int Deepth,count_node;
printf("请输入二叉树的节点:\n");
creatBiTree(T);
printf("中序线索二叉树后遍历结果:");
CreatInThread(T);
InOrder(T);
printf("\n");
}


测试结果截图如下:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: