线索二叉树的概念和存储结构
①在有 n 个结点的二叉树中必定存在 n+1 个空链域(造成空间浪费)。
②把这些空链域,建立相应结点的前驱结点信息和后继结点信息。
规定:当某结点的左指针为空时,令该指针指向中序遍历二叉树是得到的该结点的前驱结点。当某结点的右指针为空时,令该指针指向中序遍历二叉树是得到的该结点的后继结点。
③为了区别是左右孩子还是前驱后继, 我们在结点中添加两个线索
typedef struct Node//线索二叉树的结点
{
char data;
struct Node *lchild, *rchild;
int ltag, rtag;//线索的标志。0->孩子,1->前后驱
}ThrBiNode;
⑤(考试记记,学习代码可以省略)
线索:结点中指向前驱结点和后继结点的指针
线索二叉树:在二叉树的结点上添加上线索的二叉树
线索化:对二叉树以中序遍历使其变成为线索二叉树的过程称为中序遍历方法对二叉树进行的线索化。
代码(一边原理一边代码)
一:创建二叉树
算法(前序遍历):利用前序遍历的方法输入,空指针用空格代替,
void Creat__Threaded_Binary_Tree(ThrBiNode **T)
{
char c;
scanf_s("%c", &c);//输入数据
if (c == ' ')//判断数据,如果为空格,结点为空,反之。
{
*T = NULL;
}
else
{
*T = (ThrBiNode*)malloc(sizeof(ThrBiNode));//开辟空间
(*T)->data = c;//赋值数据
(*T)->ltag = 0;
(*T)->rtag = 0;
Creat__Threaded_Binary_Tree(&(*T)->lchild);//递归创建左右孩子
Creat__Threaded_Binary_Tree(&(*T)->rchild);
}
}
二:线索化(中序)
算法:①pre全局变量
②建立头结点(root),root是中序遍历的开头,并且与(中序遍历)最后的结点相连,形成环。
//全局变量
static ThrBiNode *pre;//在中序线索化遍历中的前一个结点
void In_Thread(ThrBiNode *T)//
{
if (T)
{
In_Thread(T->lchild);
if (!T->lchild)
{
T->lchild = pre;
T->ltag = 1;
}
if (!(pre)->rchild)//判断T前一个的右孩子是否有无
{//没有孩子就设成线索
(pre)->rtag = 1;
(pre)->rchild = T;
}
pre = T; //前序节点就是当前结点
In_Thread(T->rchild);
}
}
void In_root_Thread(ThrBiNode **root,ThrBiNode *T)
{
(*root) = (ThrBiNode*)malloc(sizeof(ThrBiNode));
(*root)->ltag = 0;
(*root)->rtag = 0;
(*root)->rchild = *root;//一开始,指自己
if (!T)//判断是否为空树
{
(*root)->lchild = *root;
}
else
{
(*root)->lchild = T;//root的左孩子指向根节点
pre = *root;//pre指向root结点(链型开头)
In_Thread(T);//递归线索化,退出per是中序遍历的最后一个
pre->rchild = *root;
pre->rtag = 1;
(*root)->rchild = pre;//中序遍历的最后一个结点被root的右孩子指向
}
}
三:链式遍历
void visit(char c)
{
printf("%c", c);
}
void put(ThrBiNode *T)
{
ThrBiNode *p;
p = T->lchild;
while (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;//当p->rtag==0时,直接跳到下一个。
}
}
四:主函数
#include<stdio.h>
#include<stdlib.h>
#include"InThreadIterator.h"//存放上面的所有函数
int main()
{
ThrBiNode *T, *root;
Creat__Threaded_Binary_Tree(&T);
In_root_Thread(&root, T);
printf("中序遍历二叉树的结果为:");
put(root);
printf("\n");
system("pause");
return 0;
}