- 传统的二叉树链式存储结点与结点之间只能体现父子关系,不能得到结点在遍历序列中的前驱或者后继,而且我们知道二叉树中存在大量空指针,于是我们便设想利用这些结点存放结点的前驱或者后继
- 引入线索二叉树是为了
加快查找结点前驱和后继的速度
- 在有n个结点的 二叉树中,共有
2n
个指针域,其中度为1的结点有n1个空指针域,度为0的结点有2n0
个空指针域,又n0=n2+1
,n0+n1+n2=n
,这样便能推出共有n+1
个空指针域 - 在构建线索二叉树的结点时,要新增两个标记域,0表示指向结点,1表示指向线索
- 遍历线索二叉树时不需要借助栈,也不需要递归,直接利用其线索即可,具体实现代码中有
- 线索二叉树根据遍历方式也分为前中后序线索二叉树三种
代码实现
#include <iostream>
#include<stdlib.h>
typedef struct BTnode{
char data;
struct BTnode* lchild;
struct BTnode* rchild;
int ltag,rtag;
}BTnod;
void createBTree(BTnode *&T){//创建二叉树
char ch;
scanf("%c",&ch);
if(ch=='#'){
T=NULL;
}else{
T=(BTnode *)malloc(sizeof(BTnode));
T->data=ch;
T->ltag=0;
T->rtag=0;
createBTree(T->lchild);
createBTree(T->rchild);
}
}
void inThread(BTnode *&T,BTnode *&pre){//中序遍历线索化二叉树
if(T!=NULL){
inThread(T->lchild,pre);
if(T->lchild==NULL){
T->lchild=pre;
T->ltag=1;
}
if(pre!=NULL&&pre->rchild==NULL){
pre->rchild=T;
pre->rtag=1;
}
pre=T;
inThread(T->rchild,pre);
}
}
void createInThread(BTnode *T){//创建中序线索二叉树
BTnode *pre;
pre=NULL;
if(T!=NULL){
inThread(T,pre);
pre->rchild=NULL;
pre->rtag=1;//处理最后一个结点信息
}
}
BTnode* firstNode(BTnode *p){//获取中序序列的第一个结点
while(p->ltag==0){//若有左孩子
p=p->lchild;
}
return p;
}
BTnode* nextNode(BTnode *p){//获得中序序列下T结点的后继结点
if(p->rtag==0){//若有右孩子
return firstNode(p->rchild);
}else{
return p->rchild;
}
}
void inOrderThread(BTnode *T){//遍历中序线索二叉树
BTnode *p;
for(p=firstNode(T);p!=NULL;p=nextNode(p)){
printf("%c ",p->data);
}
}
void inOrder(BTnode *T){
if(T!=NULL){
inOrder(T->lchild);
printf("%c ",T->data);
inOrder(T->rchild);
}
}
int main(int argc, char** argv) {
BTnode *T,*p;
createBTree(T);//创建二叉树
createInThread(T);//创建中序线索二叉树
inOrderThread(T);//遍历中序线索二叉树
return 0;
}
//示例输入:ab#d##c##