#include<iostream>
#include<string>
//线索二叉树结构化
template<class T>
typedef struct ThreadNode{
T elem;
struct ThreadNode *lchild,*rchild;
int ltag,rtag;
}ThreadNode,*ThreadTree;
//中序线索二叉树 线索化
//1.线索化的算法
void InThread(ThreadTree &p, ThreadTree &pre){//pre在每层递归中被修改为上层递归访问的结点
if(p != NULL){//当上个节点pre为叶子结点(没有孩子)时,孩子为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传给下一个被访问的结点
InThread(p->rchild, pre);
//当所有递归执行完时,最后一个节点的必含一个空的后继指针域
}
}
//2.执行线索化的函数
void CreateInThread(ThreadTree &T){
/*ThreadTree head,pre;//带头结点的线索二叉树
head->lchild = T;
head->ltag = 1;
pre = head;*/
ThreadTree pre = NULL;
if(T != NULL){
InThread(T,pre);
//当所有递归执行完时,最后一个节点的必含一个空的后继指针域。当前pre最后被访问的结点
pre->rtag = 1;
//pre->rchild = head;
pre->rchild = NULL;
}
}
//线索二叉树的遍历
//1.寻找中序遍历的第一个结点
ThreadNode* firstNode(ThreadNode *p){
while(p->ltag == 0){
p = p->lchild;
}
return p;
}
//2.寻找某结点的下一个节点
ThreadNode* nextNode(ThreadNode *p){
if(p->rtag == 0){//该节点有右子树,则右子树最左边的结点为下一节点
return firstNode(p->rchild);
}
else{//该节点无右孩子,rchild指向后继结点
return p->rchild;
}
}
//3.遍历
void bianli(ThreadNode* T){
for(ThreadNode*p = firstNode(T); p!=NULL; p=nextNode(p)){//p初始为第一个结点,即根节点最左边的结点
visit(p);
}
}