//
// 二叉树线索化的头文件:BinaryThreadTree.h
#ifndef B_T_T_H
#define B_T_T_H
#include <stdio.h>
//
// 返回OK表示正常返回
#define OK 1
//
// 返回ERROR,表示异常返回
#define ERROR 0
//
// 返回OVERFLOW,表示内存溢出
#define OVERFLOW -1
//
// 线索结构体
typedef enum
{
Link = 0, // 指针
Thread = 1 // 线索
}PointerTag;
//
// 树结点的数据的类型
typedef char ElemType;
//
// 返回值类型
typedef int Status;
//
// 线索二叉树结构体
typedef struct tagBinaryThreadTree
{
ElemType data;
struct tagBinaryThreadTree *lchild; // 左孩子指针
struct tagBinaryThreadTree *rchild; // 右孩子指针
PointerTag leftTag; // 左标志
PointerTag rightTag; // 右标志
}BinThrTree, *LinkBinThrTree;
//
// 按先序顺序输入数据,以建立线索二叉树
// 输入的#表示子树为空
Status CreateBinaryThreadTree(LinkBinThrTree *pBinThrTree);
//
// 中序遍历线索化二叉树
Status InOrderTraverse(LinkBinThrTree pBinThrTree);
//
// 线索化
void InThreading(LinkBinThrTree p);
//
// 中序线索化二叉树
Status InOrderThreading(LinkBinThrTree *threadTree, LinkBinThrTree tree);
#endif
//
// 线索二叉线的实现文件:BinaryThreadTree.c
#include <stdio.h>
#include <stdlib.h>
#include "BinaryThreadTree.h"
LinkBinThrTree pre = NULL; //定义pre为函数InThreading的外部变量,使其指向最后一个节点
//
// 按先序顺序输入数据,以建立线索二叉树
// 输入的#表示子树为空
Status CreateBinaryThreadTree(BinThrTree **pBinThrTree)
{
char ch;
scanf ("%c", &ch);
if (ch == '#')
{
*pBinThrTree = NULL;
}
else
{
*pBinThrTree = (LinkBinThrTree)malloc(sizeof(BinThrTree));
if (!(*pBinThrTree))
{
exit(OVERFLOW);
}
(*pBinThrTree)->data = ch;
(*pBinThrTree)->leftTag = Link;
(*pBinThrTree)->rightTag = Link;
CreateBinaryThreadTree(&(*pBinThrTree)->lchild);
CreateBinaryThreadTree(&(*pBinThrTree)->rchild);
}
return OK;
}
//
// 中序遍历线索化二叉树
Status InOrderTraverse(LinkBinThrTree pBinThrTree)
{
LinkBinThrTree p = NULL;
p = pBinThrTree->lchild;
while (p != pBinThrTree)
{
while (p->leftTag == Link)
{
p = p->lchild; // 沿着根向左走到尽头
}
printf("%c", p->data); // 输出
// 沿着线索向右走到尽头
while (p->rightTag == Thread && p->rchild != pBinThrTree)
{
p = p->rchild;
printf("%c", p->data); // 输出
}
p = p->rchild;
}
return OK;
}
//
// 线索化
void InThreading(LinkBinThrTree p)
{
if (p)
{
InThreading(p->lchild);
if (!p->lchild)
{
p->leftTag = Thread;
p->lchild = pre;
}
if (!pre->rchild)
{
pre->rightTag = Thread;
pre->rchild = p;
}
pre = p;
InThreading(p->rchild);
}
}
//
// 中序线索化二叉树
Status InOrderThreading(LinkBinThrTree *threadTree, LinkBinThrTree tree)
{
if (!((*threadTree) = (LinkBinThrTree)malloc(sizeof(BinThrTree))))
{
exit(OVERFLOW);
}
(*threadTree)->leftTag = Link;
(*threadTree)->rightTag = Thread;
(*threadTree)->rchild = (*threadTree);
if (!tree) // 若树空,左指针回指
{
(*threadTree)->lchild = (*threadTree);
}
else
{
(*threadTree)->lchild = tree;
pre = (*threadTree);
InThreading(tree);
pre->rchild = tree;
pre->rightTag = Thread;
tree->rchild = pre;
}
return OK;
}
//
// 测试线索二叉树的算法的使用
#include <stdio.h>
#include <stdlib.h>
#include "BinaryThreadTree.h"
int main()
{
BinThrTree *tree = NULL, *head = NULL;
freopen("test.txt", "r", stdin);
if (CreateBinaryThreadTree(&tree))
{
printf("二叉树创建成功!\n");
}
if (InOrderThreading(&head, tree))
{
printf("\n中序线索化二叉树完毕!\n");
}
printf("\n中序遍历线索化二叉树:\n");
InOrderTraverse(tree);
fclose(stdin);
putchar(10);
return 0;
}