二叉树一般创建时用前序遍历法,线索化时用中序遍历
线索二叉树:指向前驱后继的指针称为线索,加上线索的二叉链表为线索链表。
#include<stdio.h>
#include<stdlib.h>
typedef char ElemType;
//线索存储标志位
//Link(0):表示指向左右孩子的指针
//Thread(1):表示指向前驱后继的指针
typedef enum{Link,Thread} PointTag;
//二叉线索存储结点结构
typedef struct BitThrNode
{
ElemType data;
struct BitThrNode *lchild,*rchild;
PointTag LTag,RTag;
}BitThrNode,*BitThrTree;
//pre始终指向刚刚访问过的节点
BitThrTree pre;
//全局变量:始终指向刚刚访问过的节点
//创建一棵二叉树,约定用户遵照前序遍历的方式输入数据
void CreateBitThrTree(BitThrTree *T)
{
ElemType ch;
scanf("%c",&ch);
if(ch=='#')
*T=NULL;
else
{
*T=(BitThrTree)malloc(sizeof(BitThrNode));
(*T)->data=ch;
(*T)->LTag=Link;
(*T)->RTag=Link;
CreateBitThrTree(&(*T)->lchild);
CreateBitThrTree(&(*T)->rchild);
}
}
//中序遍历进行二叉树线索化
void InThreading(BitThrTree p)
{
if(p)
{
InThreading(p->lchild);//递归左孩子线索化
if(!p->lchild) //如果该节点没有左孩子,设置ltag为thread,并把lchild指向刚刚访问的节点
{
p->LTag=Thread;
p->lchild=pre;
}
if(!pre->rchild)
{
pre->RTag=Thread;
pre->rchild=p;
}
pre=p;
InThreading(p->rchild);//递归右孩子线索化
}
}
void InOrderThreading(BitThrTree *p,BitThrTree T)
{
*p=(BitThrTree)malloc(sizeof(BitThrNode));//创建头结点
(*p)->LTag=Link;
(*p)->RTag=Thread;
(*p)->rchild=T;
if(!T)
{
(*p)->lchild=*p;//空树指向本身
}
else
{
(*p)->lchild=T;
pre=*p;
InThreading(T);
pre->rchild=*p;
pre->RTag=Thread;
(*p)->rchild=pre;
}
}
void visit(char c)
{
printf("%c",c);
}
//中序遍历二叉树,非递归
void InOrderThaverse(BitThrTree T)//T是一个头指针了
{
BitThrTree p;//根节点
p=T->lchild;
while(p!=T)
{
while(p->LTag==Link)
{
p=p->lchild;
}
visit(p->data);
while(p->RTag==Thread&&p->rchild!=T)
{
p=p->rchild;
visit(p->data);
}
p=p->rchild;
}
}
void main()
{
BitThrTree p,T=NULL;//p是头指针,T是根节点
CreateBitThrTree(&T);
InOrderThreading(&p,T);
printf("中序遍历结果:\n");
InOrderThaverse(p);
}
运行输入:前序输入:ABC##D##E#F##
运行输出:中序输出:CBDAEF
另一种编程:
#include<stdio.h>
#include<stdlib.h>
typedef char elemtype;
typedef enum{normal,thread}node_type_t;
typedef struct node_s node_t;
typedef struct
{
node_t *ptr;
node_type_t type;
}node_ptr_t;
struct node_s
{
elemtype data;
node_ptr_t right,left;
int visited;
};
node_ptr_t *wanted=NULL;
node_t *pre=NULL;
node_t *new_node(elemtype data)
{
node_t *node=(node_t *)malloc(sizeof(node_t));
node->data=data;
node->right.ptr=NULL;
node->right.type=normal;
node->left.ptr=NULL;
node->left.type=normal;
node->visited=0;
return node;
}
void creat_tree(node_t **node)
{
elemtype ch;
scanf("%c",&ch);
if(ch==' ')
return;
else
{
*node=new_node(ch);
creat_tree(&((*node)->left.ptr));
creat_tree(&((*node)->right.ptr));
}
}
void travel_in_order(node_t *node,void (*cb)(node_t *))
{
if(!node)
return;
else
{
travel_in_order(node->left.ptr,cb);
cb(node);
travel_in_order(node->right.ptr,cb);
}
}
void print(node_t *node)
{
putchar(node->data);
}
void inthreading(node_ptr_t ptr)
{
node_t *node=ptr.ptr;
if(!node||ptr.type==thread)
return;
if(!node->left.ptr)//左孩子没有
{
node->left.ptr=pre;
if(pre)
{
node->left.type=thread;
}
}
inthreading(node->left);
if(wanted)
{
wanted->ptr=node;
wanted->type=thread;
wanted=NULL;
}
if(!node->right.ptr)//右孩子没有
{
wanted=&(node->right);
}
pre=node;
inthreading(node->right);
}
is_visit(node_t *node)
{
return node->visited;
}
is_thread(node_ptr_t ptr)
{
return ptr.type==thread ;
}
void visit_threading(node_t *node)
{
print(node);
node->visited=1;
}
void travel_with_threading(node_t *node,void cb(node_t *))
{
travel_left:
while(node->left.ptr&&!is_visit(node->left.ptr)&&!is_thread(node->left))
{
node=node->left.ptr;
}
cb(node);
if(node->right.ptr||is_thread(node->right))
{
node=node->right.ptr;
goto travel_left;
}
}
void main()
{
node_t *p;
node_ptr_t pp;
creat_tree(&p);
pp.ptr=p;
pp.type=normal;
travel_in_order(p,print);
printf("\n");
inthreading(pp);
travel_with_threading(p,visit_threading);
}