王道源码运行结果如下
//线索二叉树的链式存储结构
/
左前右后
ltag :0 lchild域指向结点的左孩子
:1 lchild域指向结点的前驱
rtag :0 rchild域指向结点的右孩子
:1 rchild域指向结点的后继
/
#include<cstdio>
#include<cstdlib>
//线索二叉树的链式存储结构
/*
左前右后
ltag :0 lchild域指向结点的左孩子
:1 lchild域指向结点的前驱
rtag :0 rchild域指向结点的右孩子
:1 rchild域指向结点的后继
*/
typedef struct TreadNode{
char data;
struct TreadNode *lchild, *rchild;
int ltag, rtag;
}ThreadNode, *ThreadTree;
void InitThreadTree(ThreadTree &bt){
bt = (ThreadTree)malloc(sizeof(ThreadNode));
bt->lchild = bt->rchild = NULL;
bt->ltag = bt->rtag = 0;
}
//按照先根序列创建一棵二叉树
const char *str = "12040035000";
void CreateThreadTree(ThreadTree &bt){
//printf("%s\n", str);
int ch = str[0];
str++;
if(ch == '0')
bt = NULL;
else{
bt = (ThreadNode*)malloc(sizeof(ThreadNode));
bt->data = ch;
bt->lchild = bt->rchild = NULL;
bt->ltag = bt->rtag = 0;
CreateThreadTree(bt->lchild);
CreateThreadTree(bt->rchild);
}
}
/*线索二叉树的构造,即二叉树的线索化,实质上就是遍历一遍二叉树,
发现该结点的左右指针域是否为空,若为空,分别将其改造成指向前驱和后继结点即可,
不要忘记改变标志位的状态*/
void InThread(ThreadTree &p, ThreadTree &pre){
if(p != NULL){
InThread(p->lchild, 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;//标记当前结点位刚刚访问过的结点
InThread(p->rchild, pre);//递归线索化右子树
}
}
//通过中序遍历建立中序线索二叉树的主过程如下
void CreateInThread(ThreadTree &T){
ThreadTree pre = NULL;
//借助一个pre指针指向中序遍历时上一个刚刚访问过的结点,表示各节点的前后关系
if(T != NULL){
InThread(T, pre);
pre->rchild = NULL;//处理遍历的最后一个结点
pre->rtag = 1;
}
}
//二叉树的中序遍历算法
void InOrderTraverse(ThreadTree bt){
if(bt != NULL){
InOrderTraverse(bt->lchild);
printf("%c", bt->data);
InOrderTraverse(bt->rchild);
}
}
//求中序线索二叉树中中序序列下的第一个结点
ThreadNode* Firstnode(ThreadNode *p){
while(p->ltag == 0)//记得创建结点时,tag初始化为0,不然找不到中序第一个结点
p = p->lchild;//最左下结点(不一定是叶子结点)
return p;
}
//求中序线索二叉树中结点p在中序序列下的后继结点
ThreadNode* Nextnode(ThreadNode *p){
if(p->rtag == 0) return Firstnode(p->rchild);//rtag == 0,右孩子存在,返回其右子树的第一个结点
else return p->rchild;//rtag == 1,直接返回其右孩子指针指向的后继结点
}
//不含头结点的中序线索二叉树的中序遍历算法
void Inorder(ThreadNode *T){
for(ThreadNode *p = Firstnode(T); p != NULL; p = Nextnode(p))
printf("%c", p->data);//记得创建结点时,tag初始化为0,不然找不到中序第一个结点
}
int main()
{
/*
1
/ \
2 3
/ \ / \
0 4 5 0
/ \ / \
0 0 0 0
*/
//对于形如上图的二叉树线索化
ThreadTree bt;
InitThreadTree(bt);
//char str[] = "12040035000";//先序次序,声明在前面的全局变量
CreateThreadTree(bt);
puts("二叉树中序遍历:");
InOrderTraverse(bt);puts("");
CreateInThread(bt);
puts("线索二叉树中序遍历:");
Inorder(bt);puts("");
/*
二叉树中序遍历:
24153
线索二叉树中序遍历:
24153
*/
return 0;
}