#include<stdio.h>
#include<stdlib.h>
//定义结构体
typedef struct node{
char data;
struct node *left, *right;
int Lflag;
int Rflag; //左右标志是左右子树还是前驱后继节点, 1: 左右子树,,0;前驱后继节点
}Node,*TreeNode;
TreeNode pre = NULL;
//利用前序创建树,若使用中序或者后序,只需调正一下语句位置
void createTree(TreeNode *T){
char data;
scanf("%c",&data);
if(T!=NULL){
if(data != '#'){
//分配内存
if(!((*T) = (Node *)malloc(sizeof(Node)))){
printf("申请内存失败!");
return;
}//赋值
else{
(*T) ->data = data;
createTree(&((*T)->left)); //初始化左子树
createTree(&((*T)->right));
}
}else{
(*T) = NULL;
}
}
}
//中序遍历
void mid_SearchTest(TreeNode T){
if(T){
mid_SearchTest(T->left);
printf("%c ", T->data);
mid_SearchTest(T->right);
}
}
//中序对二叉树进行线索化
void mid_InThreading(TreeNode T){
if(T){
mid_InThreading(T ->left); //递归左子树线索化
//如果当前节点没有左孩子,则左标志设为1,指向上一个节点pre
if(!(T->left)){
T ->Lflag = 1;
T ->left = pre;
}
//如果pre没有右节点,则右标志为1,指向下一个节点
if(pre != NULL && pre ->right ==NULL){
pre ->Rflag = 1;
//back the father
pre ->right = T;
}
pre = T; //pre 指向当前节点
mid_InThreading(T ->right); //递归右子树
}
}
//中序遍历线索二叉树
void mid_Search(TreeNode T){
while(T){
//一直找左子树,最后一个左节点输出
while(T ->Lflag != 1){
T = T ->left;
}
printf("%c ",T->data);
//当节点右标志为1时,直接找到其后继节点
while(T->Rflag == 1 && T ->right != NULL){
T = T->right;
printf("%c ",(T ->data));
}
//否则,找到其右子树的最下边的左节点遍历
T =T->right;
}
}
//双向线索二叉树,增加一个头节点,头节点的左节点指向根节点,右节点指向最后一个节点(pre:为全局变量,最后指向最后一个节点)
void doubleReaction_Thread(TreeNode *H,TreeNode T){
//为头节点申请内存
*H = (TreeNode)malloc(sizeof(Node));
if((*H) == NULL){
printf("申请内存失败!");
return;
}
(*H) ->right = *H;
(*H) ->Rflag = 0;
//若树为空
if(T == NULL){
(*H) ->left = *H;
(*H) ->Lflag = 0;
}
else{
pre = *H; //将pre指向头节点
(*H) ->left = T; //头节点·的左节点指向根节点
(*H) ->Lflag = 1;
mid_InThreading(T); //结束后,pre指向最后一个节点
//将头节点接在最后一个节点的后面
pre ->right = *H;
pre ->Rflag = 1;
(*H)->right = pre;
}
}
//中序正向遍历
void zheng_Search(TreeNode H){
TreeNode p;
p = H->left;
mid_Search(p);
}
//中序逆向
void ni_Search(TreeNode H){
TreeNode p;
p = H->right;
while(p){
while(p ->Rflag != 1){
p = p ->right;
}
printf("%c ",p ->data);
while(p->Lflag == 1 && p ->left != NULL){
p = p ->left;
printf("%c ",p ->data);
}
p = p ->left;
}
}
int main(){
TreeNode T;
TreeNode H;
printf("请输入前序遍历的序列:\n");
createTree(&T);
printf("\n");
mid_InThreading(T);
printf("请输出中序线索化二叉树序列的序列:\n");
mid_Search(T);
printf("\n");
//双向
doubleReaction_Thread(&H,T);
//正向遍历
/* printf("正向遍历: \n");
zheng_Search(H);
printf("\n");*/
printf("逆向遍历: \n");
ni_Search(H);
return 0;
}