- 普通二叉树遍历存在的缺点
1.每一次必须要从根节点出发进行遍历,而线性表的遍历可以从任何一个结点进行后续遍历。
2.以中序遍历为例:给定树中一个结点的指针,在树中找到前驱和后继结点很不方便
线索二叉树
- 基于普通二叉树存在的不便之处,利用线索二叉树解决寻找树中某一结点的前驱和后继结点
线索
:指向前驱、后继的指针成为“线索”前驱线索
:由左孩子指针
充当后继线索
:由右孩子指针
充当- 中序线索二叉树:线索指向中序前驱、中序后继
- 先序线索二叉树:线索指向先序前驱、先序后继
- 后序线索二叉树:线索指向后序前驱、后序后继
为了区分是线索还是孩子结点
用tag标志;
tag=0 表示指针指向孩子;tag=1 表示指向线索
所以一个线索二叉树结点结构体可以表示为:
typedef struct ThreadNode{
ElemType data;
struct ThreadNode *lchild,rchild;
int ltag,rtag;
}ThreadNode,ThreadTree;
下图是结构体逻辑示意图
二叉树的线索化
中序线索化
typedef struct BiTNode{
char data;
struct BiTNode *lchild, *rchild;
}BiTNode,*BiTree;
BiTNode *p;
BiTNode *pre=NULL;
BiTNode *final=NULL;
void findPre(BiTree T){
if(T!=NULL){
findPre(T->lchild);
visit(T)
findPre(T->rchild);
}
}
void visit(BiTNode *q){
if(q==p)
final = pre;
else
pre=q;
}
typedef struct ThreadNode{
ElemType data;
struct ThreadNode *lchild,rchild;
int ltag,rtag;
}ThreadNode,ThreadTree;
ThreadNode *pre=NULL;
void CreateInThread(ThreadTree 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;
}