#include <stdio.h>
#include <stdlib.h>
typedef struct Node {
char data;
int Ltag;
struct Node* LChild;
int Rtag;
struct Node* RChild;
}BitNode, * BiTree;
//先序创建二叉树
void CreatBiTree(BiTree* root) {
char ch;
ch = getchar();
if (ch == ‘.‘)
*root = NULL;
else {
*root = (BitNode*)malloc(sizeof(BitNode));
(*root)->data = ch;
(*root)->Ltag = 0;
(*root)->Rtag = 0;
CreatBiTree(&((*root)->LChild));
CreatBiTree(&((*root)->RChild));
}
}
//建立中序线索树
void InThread(BiTree root, BitNode** pre) {
if (root != NULL) {
InThread(root->LChild, pre);
/***********以中序遍历的方式添加线索***********/
//如果该节点没有左孩子,则将该节点的左指针指向其中序前驱
if (root->LChild == NULL) {
root->Ltag = 1;
root->LChild = *pre;
}
//如果该节点的中序前驱没有右孩子,则将该节点的右指针指向该节点
if (*pre != NULL && (*pre)->RChild == NULL) {
(*pre)->RChild = root;
(*pre)->Rtag = 1;
}
//将当前节点设为中序前驱
*pre = root;//这本质上还是中序遍历,因此每个节点都会成为前驱
//每一个节点都检查了其前驱与它自己的双向关系
//但是并未考虑到中序最后一个节点的右孩子指针域(所以在main函数中处理)
InThread(root->RChild, pre);
}
}
//找到中序遍历第一个节点的指针
BitNode* FindFirstNode(BiTree root) {
BitNode* p;
//寻找root的右子树中“最左下”的节点
//而其最左下的节点的中序前驱一定是NULL,所以可以这样判断
while (root != NULL) {
p = root;
root = root->LChild;
}
return p;
}
//在中序二叉树中寻找p的中序后继(返回指针)
BitNode* InNext(BitNode* p) {
BitNode* next;
BitNode* q;
if (p->Rtag == 1)//若该节点的右孩子指针指向了其中序后继
return p->RChild;//直接返回其右孩子指针
else {
q = p->RChild;//q为p的右子树
while (q->Ltag == 0)//当q的左孩子是q的中序前驱(q没有左孩子了)
q = q->LChild; //说明找到了q的右子树中最左下的节点
next = q;
return next;
}
}
//遍历中序线索二叉树
void InOrder(BiTree root) {
BitNode* p = FindFirstNode(root);//找到中序第一个节点
while (p) {
printf("%c", p->data);//输出
p = InNext(p);//找下一个节点
}
}
int main()
{
BiTree bt;
BitNode* pre = NULL;
printf("请输入一棵二叉树:\n");
CreatBiTree(&bt);
InThread(bt, &pre);//线索化
pre->Rtag = 1;//处理最后一个节点
printf("中序遍历二叉树:");
InOrder(bt);
return 0;
}

刚讲完线索二叉树,模仿课本上的程序写的。课本是耿国华的数据结构。若发现错误,望批评指正。
原文:http://www.cnblogs.com/qianbixin/p/4966794.html