xmind真好用,可以直接方便看代码,起飞
线索二叉树,如下
#include <bits/stdc++.h>
using namespace std;
#define ElemType int
typedef struct ThreadNode//线索二叉树
{
ElemType data;
struct ThreadNode *lchild,*rchild;
int ltag,rtag; //1 代表 线索 ;0 代表 非线索(即孩子节点)
}ThreadNode,*ThreadTree;
ThreadNode * pre;
void CreatThread(ThreadTree T)
{
pre = NULL;
if(T!=NULL)
{
InThread(T);
if(pre->rchild==NULL) pre->rtag=1; //这里是处理最后一个遍历的节点
} //再最后一次遍历完之后,pre会指向最后一个节点。
}
void visit(ThreadNode *q)
{
if(q->lchild==NULL) //左孩子为空,则设置该分支为线索,并且修改tag标记为1
{
q->lchild = pre;
q->ltag = 1;
}
if(pre!=NULL&&pre->rchild==NULL)//前一节点存在,且后继为空,将其转化为线索,指向当前节点
{
pre->rtag=1;
pre->rchild=q;
}
pre = q ;//该节点遍历结束了,遍历下一节点前,保存该节点。
}
void InThread(ThreadTree t)//!从中序遍历的代码出发对其visit进行重载,在每次访问一个新的节点的时候进行查询 + 操作 。
{
if(t!=NULL)
{
InThread(t->lchild);
visit(t);
InThread(t->rchild);
}//显而易见,这里是中序遍历的线索二叉树的建立
}
void creatThread(ThreadTree t)
{
ThreadNode *pr = NULL;
if(t!=NULL)
{
Inthread(t,pr);
if(pre->rchild==NULL) pre->rtag = 1;
}
}
void Inthread(ThreadTree p,ThreadTree &pr)//p是当前节点,pr是前一节点,第一次使用的时候要将pr初始化为NULL,因为第一个节点无前驱节点
{
if(p!=NULL)
{
Inthread(p->lchild,pr); //左
if(p->lchild==NULL)//相当于visit的操作 //根
{
p->ltag=1;
p->lchild = pr;
}
if(pr!=NULL&&pr->rchild==NULL)
{
pr->rchild = p;
pr->rtag = 1;
}
pr = p;
Inthread(p->rchild,pr); //右
}
}