本篇创建的是二叉搜索树,代码包含二叉搜索树的建树以及树的线索化和线索化后的遍历。
完整代码如下:
#include<stdio.h>
#include<stdlib.h>
typedef struct LinkedTree
{
int data, ltag, rtag; // 数据域,左线索,右线索
struct LinkedTree* rchild;
struct LinkedTree* lchild;
}TNode;
TNode* CreatNode(int data)//创建一个节点并初始化
{
TNode* p = NULL;
p = (TNode*)malloc(sizeof(TNode));
if (p)
{
p->data = data;
p->ltag = 0;
p->rtag = 0;
p->lchild = NULL;
p->rchild = NULL;
}
else
{
printf("Malloc Error!\n");
return NULL;
}
return p;
}
void AddNode(int data, TNode* p)//递归插入数据
{
if (data == p->data)
{
return;
}
if (data < p->data)
{
if (p->lchild)
{
AddNode(data, p->lchild);
}
else
{
p->lchild = CreatNode(data);
}
}
else
{
if (p->rchild)
{
AddNode(data, p->rchild);
}
else
{
p->rchild = CreatNode(data);
}
}
}
TNode* CreateTree(void)//建树
{
int data = 0;
TNode* root = NULL;
printf("请输入数据(输入-1结束):");
while (1)
{
scanf_s("%d", &data);
if (-1 == data)
{
break;
}
if (root)
{
AddNode(data, root);
}
else
{
root = CreatNode(data);
}
}
return root;
}
void InOrder(TNode* p)//中序遍历
{
if (p)
{
InOrder(p->lchild);
printf("%d ", p->data);
InOrder(p->rchild);
}
}
void InThreadTree(TNode* p, TNode** pre)//中序线索化二叉树,在中序遍历的过程中线索化二叉树
{ //*pre记录前驱,使用二级指针,也可以声明一个为全局变量pre指针
if (p)
{
InThreadTree(p->lchild, pre);
if (!p->lchild)
{
p->ltag = 1;
}
if (!p->rchild)
{
p->rtag = 1;
}
if ((*pre) != NULL)
{
if (1 == (*pre)->rtag)//前驱(*pre)的右线索为1,前驱的右孩子为空
{
(*pre)->rchild = p;//设置(*pre)的后继
}
if (1 == p->ltag)//当前节点左孩子为为空
{
p->lchild = (*pre);//设置当前节点的前驱
}
}
(*pre) = p;//保存当前节点为前驱
InThreadTree(p->rchild, pre);
}
}
void InOrderThred(TNode* p)//遍历线索化后的二叉树树
{
while (p->ltag != 1)//遍历找到左下节点
{
p = p->lchild;
}
while (p)
{
printf("%d ", p->data);
if (1 == p->rtag)//右子树为空
{
p = p->rchild;
}
else //右子树不为空的情况
{
p = p->rchild;
while (p->ltag != 1)//遍历找到该子树的左下节点
{
p = p->lchild;
}
}
}
}
void FreeTree(TNode* p)//释放二叉树,根据InThred(List* p)函数改动,在遍历的时候free节点
{
TNode* q = NULL; //使用q指针记录p的下一节点
while (p->ltag != 1)
{
p = p->lchild;
}
while (p)
{
if (1 == p->rtag) //右子树为空
{
q = p->rchild; //记录下一节点
free(p);
p = q;
}
else
{
q= p->rchild; //记录下一节点
free(p);
p = q;
while (p->ltag != 1)
{
p = p->lchild;
}
q = p;
}
}
}
int main(void)
{
TNode* pre = NULL;
TNode* root = CreateTree();
printf("中序遍历:");
InOrder(root);
putchar('\n');
InThreadTree(root, &pre);
printf("线索化后的遍历:");
InOrderThred(root);
putchar('\n');
FreeTree(root);
return 0;
}
运行环境vs2019,有问题的地方还请指出。