一、中序线索化
中序线索二叉树是不会出现前驱节点pre的右孩子和当前节点p的左孩子同时为空的情况如图1,也即代码中标注的两个if语句不会同时成立

中序遍历线索二叉树的结果如图2

通过中序遍历对二叉树线索化的递归算法
typedef struct ThreadNode{
char 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){//中序线索化中两个 if 语句不会同时成立
pre->rchild = p
pre->rtag = 1
}
pre=p
InThread(p->rchild,pre)
}//end p!=NULL
}
void CreateInThread(ThreadTree T){
ThreadTree pre = NULL
if(T!=NULL){
InThread(T,pre)
pre->rchild=NULL
pre->rtag=1
}
}
二、前序线索化
前序线索二叉树会出现前驱节点pre的右孩子和当前节点p的左孩子同时为空的情况但并不是两种情况都会存在,即如果存在只能是图3左边这种情况,如图3所示

前序遍历线索二叉树的结果如图4,由于会出现上数的第一种情况,我们必须要对代码进行处理,否则前序线索化的程序会无线递归下去

通过前序遍历对二叉树线索化的递归算法
void PreThread(ThreadTree &p,ThreadTree &pre){
if(p!=NULL){//前序线索化中两个 if 语句会同时成立
if(p->lchild==NULL){
p->lchild = pre
p->ltag = 1
}
if(pre!=NULL&&pre->rchild==NULL){
pre->rchild = p
pre->rtag = 1
}
pre=p
if(p->ltag==0)//只有左孩子不是线索时才线索化左子树
PreThread(p->lchild,pre)
PreThread(p->rchild,pre)
}//end p!=NULL
}
void CreatePreThread(ThreadTree T){
ThreadTree pre = NULL
if(T!=NULL){
PreThread(T,pre)
if(pre->rchild=NULL)//这里不需要判断最后一个节点是否为空就也可直接处理
pre->rtag=1
}
}
三、后序线索化
后序线索二叉树会出现前驱节点pre的右孩子和当前节点p的左孩子同时为空的情况但并不是两种情况都会存在,即如果存在只能是图5右边这种情况,如图5所示

后序遍历线索二叉树的结果如图6,后序因为先递归再处理,所以不会出现无限递归的现象,故无需特殊处理

通过后序遍历对二叉树线索化的递归算法
void PostThread(ThreadTree &p,ThreadTree &pre){
PostThread(p->lchild,pre)
PostThread(p->rchild,pre)
if(p!=NULL){//后序线索化中两个 if 语句会同时成立
if(p->lchild==NULL){
p->lchild = pre
p->ltag = 1
}
if(pre!=NULL&&pre->rchild==NULL){
pre->rchild = p
pre->rtag = 1
}
pre=p
}//end p!=NULL
}
void CreatePostThread(ThreadTree T){
ThreadTree pre = NULL
if(T!=NULL){
PreThread(T,pre)
if(pre->rchild=NULL)//这里需要判断最后一个节点是否为空
pre->rtag=1
}
}