优势:便于在中序遍历下,查找前驱和后继。
前驱/后继含义:AB中,A是B前驱,B是A后继。
ltag=0时:lchild指向左孩子 ltag=1时:lchild指向前驱
rtag=0时:rchild指向右孩子 rtag=1时:rchild指向后继
过程:
1、先前序遍历创建二叉树
2、线索化二叉树
3、线索二叉树中序遍历输出
总代码:
//线索二叉树
//优势:便于在中序遍历下,查找前驱和后继
#include<stdio.h>
#include<malloc.h>
#include<string>
int index = 0;
int first = 1;
char str[30];
typedef enum { Link, Thread } PointerTag; //0:Link(指向结点) 1:Thread(指向线索)
typedef struct BiThTree
{
char data;
struct BiThTree* lchild, * rchild; //左孩子、右孩子
PointerTag ltag, rtag; //0:指向左/右孩子; 1:指向前驱/后继
struct BiThTree* parent; //指向双亲结点
}BiThTree;
BiThTree* head; //头
BiThTree* Pre; //前一个结点
void Init_BiThTree()
{
head = (BiThTree*)malloc(sizeof(BiThTree));
head->parent = head;
}
//前序遍历创建二叉树
void Create_BiThTree(BiThTree* T)
{
if (str[index] == '#') //空
{
T->data = str[index++];
return;
}
T->parent = Pre; //保存前一个结点
T->data = str[index++];
T->lchild = (BiThTree*)malloc(sizeof(BiThTree));
T->rchild = (BiThTree*)malloc(sizeof(BiThTree));
T->ltag = Link;
T->rtag = Link;
Pre = T; //保存前一个结点
Create_BiThTree(T->lchild);
Create_BiThTree(T->rchild);
}
//线索化二叉树(中序)
void InThreading(BiThTree* T)
{
//如果存在
if (T->data != '#')
{
InThreading(T->lchild); //递归左子树
//线索化左
if (T->lchild->data == '#') //lchild为空,lchild指向前驱
{
T->ltag = Thread; //线索模式
if (first) //首个赋空
{
T->lchild->data = '#';
first = 0;
}
else
T->lchild = Pre; //lchild指向前驱
}
//线索化右
else if (Pre->rchild->data == '#') //前驱的rchild为空,前驱的rchild指向后继
{
Pre->rtag = Thread; //线索模式
Pre->rchild = T; //rchild指向后继
}
Pre = T;
InThreading(T->rchild); //递归右子树
}
}
//线索二叉树中序遍历
void InOrderThTraverse(BiThTree* T)
{
if (T->data != '#')
{
if (T->ltag == Link)
InOrderThTraverse(T->lchild);
printf("%c结点 \tlchild:%c\trchild:%c\n", T->data, T->lchild->data, T->rchild->data);
if (T->rtag == Link)
InOrderThTraverse(T->rchild);
}
}
int main()
{
printf("请按照前序遍历顺序输入需要创建的二叉树结点:\n");
scanf_s("%s", str, 20);
Init_BiThTree(); //初始化
Create_BiThTree(head); //前序遍历创建二叉树
Pre = head;
InThreading(head); //中序线索化二叉树
InOrderThTraverse(head); //线索二叉树中序遍历
}