/*
線索二叉樹
運行環境: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;
}