【线索二叉树的啦啦啦啦啦~】
附设一个指针pre始终指向刚刚访问过的结点,而指针 p指向当前访问的结点。由于线索二叉树构造的实质是将二叉链表中的空指针改为指向前驱或后继的线索,而前驱或 后继的信息只有在遍历时才能得到,因此线索化的过程即为在遍历的过程中修改空指针的过程, 可用递归算法。对二叉树按照不同的遍历次序进行线索化,可以得到不同的线索二叉树,包括先 序线索二叉树、 中序线索二叉树和后序线索二叉树。下面重点介绍中序线索化的算法。
#include<bits/stdc++.h>
using namespace std;
typedef int Status;
typedef char TElemType;
#define OVERFLOW -1
#define ERROR 0
#define OK 1
//-----线索二叉树的存储表示-----
typedef struct BiThrNode
{
TElemType data;
struct BiThrNode *lchild, *rchild; //左右孩子指针
int LTag, RTag; //左右标志
}BiThrNode, *BiThrTree;
BiThrTree T, Thrt;
BiThrNode *pre = new BiThrNode;
BiThrNode *p;
//1、以结点p为根的子树中序线索化
void InThreading(BiThrTree p)
{//pre是全局变址,初始化时其右孩子指针为空,便于在树的最左点开始建线索
if(p)
{
InThreading(p->lchild); //左子树递归线索化
if(!p->lchild) //p的左孩子为空
{
p->LTag = 1; //给p加上左线索
p->lchild = pre; //p的左孩子指针指向pre (前驱)
}
else
p->LTag = 0;
if(!pre->rchild) //pre的右孩子为空
{
p->RTag = 1; //pre的右孩子指针指向p (后继)
pre->rchild = p;
}
else
p->RTag = 0;
pre = p; //保持pre指向p的前驱
InThreading(p->rchild); //右子树递归线索化
}
}
//2、带头结点的二叉树中序线索化 (么看懂,,,,,,
void InOderThreading(BiThrTree &Thrt, BiThrTree T)
{//中序遍历二叉树 T, 并将其中序线索化,Thrt指向头结点
Thrt = new BiThrNode;
Thrt->LTag = 0;
Thrt->RTag = 1;
Thrt->rchild = Thrt;
if(!T)
Thrt->lchild = Thrt;
else
{
Thrt->lchild = T;
pre = Thrt;
InThreading(T);
pre->rchild = Thrt;
pre->RTag = 1;
Thrt->rchild = pre;
}
}
//3、中序遍历线索二叉树 (又么看懂,,,,,,
void InOrderTraverse_Thr(BiThrTree T)
{//T指向头结点,头结点的左链lchild指向根结点,
//中序遍历二叉线索树T的非递归算法,对每个数据元素直接输出
p = T->lchild;
while(p != T)
{
while(p->LTag == 0)
p = p->lchild;
cout<<p->data;
while(p->RTag == 1 && p->rchild != T)
{
p = p->rchild;
cout<<p->data;
}
p = p->rchild;
}
}