线索二叉树C/C++
遍历二叉树就是以一定规则将二叉树中的节点排列成一个线性序列,从而得到二叉树节点的各种遍历序列。其实质就是对一个非线性序列进行线性化操作,使得在这个访问序列中每一个节点(除第一个和最后一个)都有一个直接前驱和直接后继。
n个结点的二叉链表中含有n+1(2n-(n-1)=n+1)个空指针域。利用二叉链表中的空指针域,存放指向结点在某种遍历次序下的前趋和后继结点的指针(这种附加的指针称为”线索”)。
因此,修改二叉树结点的定义,加入两个标志域,0为指针,1为线索,重新定义如下:
typedef enum{Link, Thread} PointerTag;
//线索存储标志位
//Link(0):表示指向左右孩子的指针
//Thread(1):表示指向前驱或后继的线索
typedef struct BiThrNode{
TElemType data;
struct BiThrNode *lchild, *rchild;
PointerTag ltag, rtag;
}BiThrNode;
算法如下:
/*递归中序线索化二叉树*/
#include <iostream>
#include <malloc.h>
using namespace std;
#define TElemType char
typedef enum{Link, Thread} PointerTag;
//线索存储标志位
//Link(0):表示指向左右孩子的指针
//Thread(1):表示指向前驱或后继的线索
typedef struct BiThrNode{
TElemType data;
struct BiThrNode *lchild, *rchild;
PointerTag ltag, rtag;
}BiThrNode;
void CreatBiThreadTree(BiThrNode *&T)
{
char e;
cin>>e;
if(e == '#') T = NULL;
else{
T = (BiThrNode *) malloc (sizeof(BiThrNode));
T->data = e;
T->ltag = T->ltag = Link;
CreatBiThreadTree(T->lchild);
CreatBiThreadTree(T->rchild);
}
}
void InOrderTraverse(BiThrNode *T)
{
if(T){
InOrderTraverse(T->lchild);
cout<<T->data;
InOrderTraverse(T->rchild);
}
}
//中序递归线索化算法
void InThreading(BiThrNode *&T,BiThrNode *&pre)
{
if(T){
InThreading(T->lchild, pre); //递归左孩子线索化
if(!T->lchild){
T->ltag = Thread;
T->lchild = pre;
}
if(!pre->rchild){
pre->rtag = Thread;
pre->rchild = T;
}
pre = T;
InThreading(T->rchild, pre); //递归右孩子线索化
}
}
BiThrNode *InOrderThrTree(BiThrNode *T)
{
BiThrNode *Thre, *pre;
Thre = (BiThrNode *) malloc (sizeof(BiThrNode)); //创建一个结点,左指针指向二叉树根结点,右结点指向自身
Thre->lchild = T;
Thre->rchild = Thre;
pre = Thre;
InThreading(T, pre); //中序递归线索化
pre->rtag = Thread;
pre->rchild = Thre;
Thre->rchild = pre;
return Thre;
}
void InOrderThreading(BiThrNode *Thre)
{
BiThrNode *p;
p = Thre->lchild;
while(p != Thre){ //指针p指回Thre时,遍历结束
while(p->ltag == Link) p = p->lchild; //左标志位为指针,则向左走
cout<<p->data;
while(p->rtag == Thread && p->rchild != Thre){ //右标志位为线索,并且右孩子不指回Thre,访问p结点后继一次并输出一次
p = p->rchild;
cout<<p->data;
}
p = p->rchild; //左孩子为空,右线索为指针,则向右移动一次
}
cout<<endl;
}
int main()
{
BiThrNode *t = NULL;
BiThrNode *thre;
CreatBiThreadTree(t);
cout<<"中序遍历:";
InOrderTraverse(t);
cout<<"\n线索化中序遍历:";
thre = InOrderThrTree(t);
InOrderThreading(thre);
return 0;
}