/*
线索二叉树
运行环境:vs2010
*/
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <string.h>
#define NIL '#'
#define OK 1
#define ERROR 0
typedef struct thread_bitree_node thrbitree;
typedef enum
{
LINK, //指针
THREAD //线索
}pointer_tag;
struct thread_bitree_node
{
char elem;
thrbitree *lchild;
thrbitree *rchild;
pointer_tag ltag;
pointer_tag rtag;
};
/*
功能:先序创建二叉树
返回:创建的节点地址
*/
thrbitree *create_thread_bitree()
{
char elem;
thrbitree *thrbtn = NULL;
fflush(stdin); //清空输入缓冲流
scanf("%c", &elem);
if(elem == NIL)
{
return thrbtn;
}
else
{
thrbtn = (thrbitree *)malloc(sizeof(thrbitree));
thrbtn->elem = elem;
thrbtn->lchild = create_thread_bitree();
if(thrbtn->lchild)
{
thrbtn->ltag = LINK;
}
else
{
thrbtn->ltag = THREAD;
}
thrbtn->rchild = create_thread_bitree();
if(thrbtn->rchild)
{
thrbtn->rtag = LINK;
}
else
{
thrbtn->rtag = THREAD;
}
return thrbtn;
}
}
thrbitree *pre; //全局变量,指向刚刚访问过的结点
//进行中序线索化
void in_threading(thrbitree *thrbtn)
{
if(thrbtn)
{
in_threading(thrbtn->lchild); //递归线索化左子树
if(!thrbtn->lchild) //没有左孩子
{
thrbtn->ltag = THREAD;
thrbtn->lchild = pre;
}
if(!pre->rchild) //前驱没有右孩子
{
pre->rtag = THREAD;
pre->rchild = thrbtn;
}
pre = thrbtn;
in_threading(thrbtn->rchild); //递归线索化右子树
}
}
//中序遍历二叉树T,并将其中序线索化
thrbitree *inorder_threading(thrbitree *thrbtn)
{
thrbitree *head = NULL;
head = (thrbitree *)malloc(sizeof(thrbitree));
memset(head, 0, sizeof(thrbitree));
if(!head)
{
exit(ERROR);
}
head->ltag = LINK;
head->rtag = THREAD;
head->rchild = head;
if(!thrbtn) //二叉树为空
{
head->lchild = head;
}
else
{
head->lchild = thrbtn;
pre = head;
in_threading(thrbtn);
//最后一个结点线索化
pre->rchild = head;
pre->rtag = THREAD;
head->rchild = pre;
}
return head;
}
/*
中序遍历二叉树并打印
*/
int inorder_print_threadbitree(thrbitree *headthbtn, int (*visit)(char))
{
thrbitree *p = NULL;
p = headthbtn->lchild;
while(p != headthbtn) //空树或者遍历结束时,p==headthbtn
{
while(p->ltag == LINK)
{
p = p->lchild;
}
visit(p->elem);
while((p->rtag == THREAD) && (p->rchild != headthbtn))
{
p = p->rchild;
visit(p->elem);
}
p = p->rchild;
}
return OK;
}
/*
功能:打印传入的参数值
*/
int print_elem(char elem)
{
printf("%c ", elem);
return OK;
}
/*
测试数据:abd###c##
中序遍历:dbac
*/
int main()
{
thrbitree *thrbtn = NULL;
thrbitree *headthrbtn = NULL;
thrbtn = create_thread_bitree();
headthrbtn = inorder_threading(thrbtn);
inorder_print_threadbitree(headthrbtn, print_elem);
printf("\n");
system("pause");
return 0;
}