1:
当使用非递归遍历二叉树时仍要开一个用户栈,而构建了线索二叉树后就不需要再开栈了,可以节省不少空间。
因为线索二叉树是用链表储存的,可以非常快的找到前驱或后继节点。
首先,中序创建线索二叉树的代码如下。
struct TBTNode{
chat data;
struct TBTNode *lchild;
struct TBTNode*rchild;
int ltag;
int rtag;
};
void INThread(TBTNode *p,TBTNode *&pre){
if(p!=NULL){
INThread(P->lchild,pre);
if(p->lchild==NULL){
p->ltag=1;
p->lchild=pre;
}
if(pre->rchild==NULL&&pre!=NULL){
pre->rchild=p;
pre->rtag=1;
}
pre=p;
INThread(p->rchild,pre);
}
}
注意中序递归遍历的框架的构建,说白了,就是中序遍历的同时,进行线索的连接。
2:
线索二叉树的前序遍历的构建,代码如下:
void preThread(TBTNode *p,TBTNode *&pre){
if(p!=NULL){
if(p!=NULL){
if(p->lchild==NULL){
p->ltag=1;
p->lchild=pre;
}
if(pre->lchile=NULL&&pre!=NULL){
pre->rtag=1;
pre->rchild=p;
}
if(p->ltag==0)//注意递归条件的判断
preThread(p->rchild,pre);
if(p->rtag==0)//注意递归条件的判断
preThread(p->lchild,pre);
}
}
}
此代码有一个需要注意的地方即递归条件的控制。当此节点存在左右子树时才需要进行递归,那么,可能会有疑问,开头的
if(p!=NULL)不就是控制递归结束的条件?不错,此就是控制条件,但是不要忘了,这是前序遍历的条件下,所以是先构建条件后进行递归,即拿任意一个叶子节点来说,当p是叶子节点,此时p->lchild=pre,所以P->lchild不再是NULL,所以如果不加以控制,那么递归就永远不会停止!
3:
后序遍历下的线索二叉树的构建,代码如下:
void postThread(TBTNode*p,TBTNode *&pre){
if(p!=NULL){
postThread(p->lchild,pre);
postThread(p->rchild,pre);
if(p->lchild==NULL){
p->ltag=1;
p->lchild=pre;
}
if(pre!=NULL&&pre->rchild==NULL){
pre->rchild=p;
pre->ltag=1;
}
pre=p;
}
}
掌握好后序遍历的递归框架!
//通过中序遍历构建线索二叉树的主程序。
void creatInThread(TBTNode *root){
TBTNode*pre;
if(root!=NULL){//当二叉树是非空的时候再对其进行处理
InThread(root ,pre);
pre ->rchild=NULL;//对最后一个节点进行处理。
pre->rtag=1;
}
}