一、中序线索化
//中序线索化二叉树
//线索二叉树结点
typedef struct ThreadNode{
ElemType data;
struct ThreadNode *lchild,*rchild;
int ltag,rtag; //左右线索标志,0为结点,1为线索
}ThreadNote,* ThreadTree;
ThreadNode *pre = NULL; //全局变量pre,指向当前访问结点的前驱
//中序线索化二叉树
void CreateInThread(Thread T){
pre = NULL;
if(T!=NULL){
InThread(T);
if(pre->rchild == NULL)
pre->rtag=1;
}
}
//中序遍历二叉树,一边遍历一边线索化
void InThread(ThreadTree T){
if(T!=NULL){
InThread(T->lchild);
visit(T);
InThread(T->rchild);
}
}
void visit(ThreadNode *q){ //左子树为空,建立前驱结点
if(q->lchild==NULL){
q->lchild=pre;
q->ltag=1;
}
if(pre!=NULL&&pre->rchild==NULL){
pre->rchild=q; //建立前驱结点的后继线索
pre-<rtag=1;
}
pre=q;
}
二、先序线索化
在先序线索化二叉树时,当访问左孩子时有可能访问到了左线索指向的前驱,因此需要在访问节点左孩子之前对ltag标志进行判断,看是线索前驱节点还是左孩子。
//先序线索化二叉树
//线索二叉树结点
typedef struct ThreadNode{
ElemType data;
struct ThreadNode *lchild,*rchild;
int ltag,rtag; //左右线索标志,0为结点,1为线索
}ThreadNote,* ThreadTree;
ThreadNode *pre = NULL; //全局变量pre,指向当前访问结点的前驱
//先序线索化二叉树
void CreatePreThread(Thread T){
pre = NULL;
if(T!=NULL){
PreThread(T);
if(pre->rchild == NULL)
pre->rtag=1;
}
}
//先序遍历二叉树,一边遍历一边线索化
void PreThread(ThreadTree T){
if(T!=NULL){
visit(T);
if(T->rtag==0) //当lchild不是前驱线索,才能访问
PreThread(T->lchild);
PreThread(T->rchild);
}
}
void visit(ThreadNode *q){ //左子树为空,建立前驱结点
if(q->lchild==NULL){
q->lchild=pre;
q->ltag=1;
}
if(pre!=NULL&&pre->rchild==NULL){
pre->rchild=q; //建立前驱结点的后继线索
pre-<rtag=1;
}
pre=q;
}
三、后序线索化
//后序线索化二叉树
//线索二叉树结点
typedef struct ThreadNode{
ElemType data;
struct ThreadNode *lchild,*rchild;
int ltag,rtag; //左右线索标志,0为结点,1为线索
}ThreadNote,* ThreadTree;
ThreadNode *pre = NULL; //全局变量pre,指向当前访问结点的前驱
//后序线索化二叉树
void CreatePostThread(Thread T){
pre = NULL;
if(T!=NULL){
PostThread(T);
if(pre->rchild == NULL)
pre->rtag=1;
}
}
//后序遍历二叉树,一边遍历一边线索化
void PostThread(ThreadTree T){
if(T!=NULL){
PostThread(T->lchild);
PostThread(T->rchild);
visit(T);
}
}
void visit(ThreadNode *q){ //左子树为空,建立前驱结点
if(q->lchild==NULL){
q->lchild=pre;
q->ltag=1;
}
if(pre!=NULL&&pre->rchild==NULL){
pre->rchild=q; //建立前驱结点的后继线索
pre-<rtag=1;
}
pre=q;
}