直接上代码。
#include<iostream>
#include<cstdio>
using namespace std;
#define OK 1
#define ERROR 0
typedef int Status;
typedef char TElemType;
/*
定义线索二叉树的数据结构
*/
typedef struct BiThrNode
{
char data;//结点对应的数据
int ltag, rtag;//左右孩子标记
struct BiThrNode *lchild;//左孩子
struct BiThrNode *rchild;//右孩子
}BiThrNode,*BiThrTree;
/*
输出对应结点里面的值
*/
Status PrintElement(TElemType e)
{
cout << e;
return OK;
}
/*
寻找p结点在Thrt树中的父节点,便于进行后序遍历
*/
BiThrTree parent(BiThrTree &Thrt, BiThrTree &p)
{
BiThrTree temp=Thrt->lchild;
if (p==Thrt->lchild)//p即为根节点,返回创建的头结点
{
return Thrt;
}
if (temp->lchild == p)
{
return temp;//父节点就是我们寻找的结点
}
else
{
temp = temp->lchild;
while (temp->lchild != p&&temp->rchild != p)
{
/*
如果节点有右孩子,那就往右
如果节点没有右孩子,就往左
没有左孩子,就往前驱
*/
if (temp->rtag == 0)
{
temp = temp->rchild;
}
else
{
temp = temp->lchild;
}
}
return temp;
}
}
/*
创建线索二叉树,初始化跟二叉树的初始化递归算法一样
*/
Status CreateBiThrTree(BiThrTree &T)
{
char ch;
cin >> ch;
if (ch == '#')
T = NULL;
else
{
if (!(T = (BiThrNode *)malloc(sizeof(BiThrNode))))
exit(OVERFLOW);
T->data = ch;
T->ltag = 0;
T->rtag = 0;
CreateBiThrTree(T->lchild);
CreateBiThrTree(T->rchild);
}
return OK;
}
/*
T指向头结点,头结点的左链lchild指向根节点
中序遍历二叉线索树T的非递归算法,对每个数据元素调用函数Visit
*/
Status InOrderTraverse_Thr(BiThrTree T, Status(*Visit)(TElemType e))
{
BiThrTree p = T->lchild;
while (p&&(p != T))
{
while (p->ltag == 0)
{
p = p->lchild;
}
Visit(p->data);
while (p->rtag == 1 && p->rchild != T)
{
p = p->rchild;
Visit(p->data);
}
p = p->rchild;
}
return OK;
}
/*
前序遍历二叉树非递归算法(仿造中序遍历)
*/
Status PreOrderTraverse_Thr(BiThrTree T, Status(*Visit)(TElemType e))
{
BiThrTree p = T;
while (p)
{
while (p->ltag == 0)
{
Visit(p->data);
p = p->lchild;
}
Visit(p->data);
p = p->rchild;
}
return OK;
}
/*
后序遍历二叉树非递归算法
*/
Status PostOrderTraverse_Thr(BiThrTree T, Status(*Visit)(TElemType e))
{
BiThrTree p = T->lchild;
BiThrTree pre = T;
//p指向第一个被访问结点
while (p->ltag == 0||p->rtag==0)
{
while(p->ltag==0)
p = p->lchild;
if (p->rtag == 0)
p = p->rchild;
}
while (p != T)
{
Visit(p->data);
pre = parent(T, p);//找到该节点的双亲
if (T == pre)//如果双亲是T,就说明p是根节点,无后继
{
p = T;
}
//如果p是双亲的右孩子,或者双亲无右孩子,则后继为双亲
else if(p==pre->rchild||pre->rtag==1)
{
p = pre;
}
else
{
//若p的双亲有右孩子,后继为双亲右子树上后序遍历的第一个孩子
while (pre->rtag == 0)
{
pre = pre->rchild;
while (pre->ltag == 0)
{
pre = pre->lchild;
}
}
p = pre;
}
}
return OK;
}
/*
中序遍历进行二叉树线索化
*/
void InThreading(BiThrTree p,BiThrTree &pre)
{
if (p)
{
InThreading(p->lchild,pre);//左子树线索化
if (!p->lchild)
{
p->ltag = 1;
p->lchild = pre;
}
if ((!pre->rchild)&&pre->rchild==NULL)
{
pre->rtag = 1;
pre->rchild = p;
}
pre = p;
InThreading(p->rchild, pre);//右子树线索化
}
}
/*
前序遍历进行二叉树线索化
*/
void preThreading(BiThrTree p, BiThrTree &pre)
{
if (p)
{
if (p->lchild == NULL)
{
p->lchild = pre;
p->ltag = 1;
}
if (pre != NULL&&pre->rchild == NULL)
{
pre->rchild = p;
pre->rtag = 1;
}
pre = p;
if (p->ltag == 0)
preThreading(p->lchild, pre);
if (p->rtag == 0)
preThreading(p->rchild, pre);
}
}
/*
后序遍历进行线索二叉树化
*/
void postThreading(BiThrTree p, BiThrTree &pre)
{
if (p)
{
postThreading(p->lchild, pre);
postThreading(p->rchild, 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;
}
}
/*
中序遍历二叉树T,并将其中序线索化,Thrt指向头结点
*/
Status InOrderThreading(BiThrTree &Thrt, BiThrTree T)
{
//建立头结点
if (!(Thrt = (BiThrTree)malloc(sizeof(BiThrNode))))
exit(OVERFLOW);
Thrt->ltag = 0;
Thrt->rtag = 1;
Thrt->rchild = Thrt;//右指针回指
BiThrTree pre;
if (!T)
Thrt->lchild = Thrt;//若二叉树为空,则指针回指
else
{
Thrt->lchild = T;
pre = Thrt;
InThreading(T,pre);//中序遍历进行中序线索化
pre->rchild = Thrt;//最后一个结点线索化
pre->rtag = 1;
Thrt->rchild = pre;
}
return OK;
}
/*
后序遍历二叉树,并将其线索化,原理同中序
*/
Status PostOrderThreading(BiThrTree &Thrt, BiThrTree T)
{
//建立头结点
if (!(Thrt = (BiThrTree)malloc(sizeof(BiThrNode))))
exit(OVERFLOW);
Thrt->ltag = 0;
Thrt->rtag = 1;
Thrt->rchild = Thrt;//右指针回指
BiThrTree pre;
if (!T)
Thrt->lchild = Thrt;//若二叉树为空,则指针回指
else
{
Thrt->lchild = T;
pre = NULL;
postThreading(T, pre);//后序遍历进行后序线索化
pre->rchild = Thrt;
pre->rtag = 1;
Thrt->rchild = pre;//最后一个结点线索化
}
return OK;
}
void main()
{
BiThrTree T1, Thrt1;
cout << "创建线索二叉树,按先序次序输入线索二叉树中结点的值:\n";
CreateBiThrTree(T1);
if (InOrderThreading(Thrt1, T1) == OK)
cout << "成功建立中序线索化链表!\n";
cout << "中序遍历线索二叉树,结果是:\n";
InOrderTraverse_Thr(Thrt1, PrintElement);
cout << endl;
BiThrTree T2;
cout << "创建线索二叉树,按先序次序输入线索二叉树中结点的值:\n";
CreateBiThrTree(T2);
BiThrTree test1 = T2;
preThreading(T2, test1);
cout << "前序遍历线索二叉树,结果是:\n";
PreOrderTraverse_Thr(T2, PrintElement);
cout << endl;
BiThrTree T3,Thrt3;
cout << "创建线索二叉树,按先序次序输入线索二叉树中结点的值:\n";
CreateBiThrTree(T3);
if (PostOrderThreading(Thrt3, T3) == OK)
cout << "成功建立后序序线索化链表!\n";
cout << "后序遍历线索二叉树,结果是:\n";
PostOrderTraverse_Thr(Thrt3, PrintElement);
cout << endl;
system("pause");
}