2.4b 中序线索二叉树_代码_哔哩哔哩_bilibili
//中序线索二叉树
#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
// 线索二叉树结点的定义
typedef struct ThreadNode{
char data;
struct ThreadNode *lchild, *rchild;
int ltag, rtag; //左、右线索标记
}ThreadNode,*ThreadTree;
ThreadTree pre=NULL; //全局变量pre, 指向当前访问结点的前驱
//建立前驱线索和后继线索
void visit(ThreadTree q){
if(q->lchild==NULL){
q->lchild=pre; //建立当前结点的前驱线索
q->ltag=1;
}
if(pre!=NULL && pre->rchild==NULL){
pre->rchild=q; //建立前驱结点的后继线索
pre->rtag=1;
}
pre=q;
}
//中序线索化二叉树
void InThread(ThreadTree T){
if(T==NULL) return;
InThread(T->lchild); //中序遍历左子树
visit(T); //访问根节点
InThread(T->rchild); //中序遍历右子树
}
//建立中序线索二叉树
void CreateInThread(ThreadTree T){
InThread(T); //中序线索化二叉树
if(pre->rchild==NULL)
pre->rtag=1; //处理最后一个结点
}
//找到以p为根的子树中,第一个被中序遍历的结点
ThreadTree FirstNode(ThreadTree p){
//循环找到最左下结点(不一定是叶结点)
while(p->ltag==0) p=p->lchild;
return p;
}
//在中序线索二叉树中找到结点p的后继结点
ThreadTree NextNode(ThreadTree p){
if(p->rtag==0) //若p有右子树
return FirstNode(p->rchild); //右子树中最左下的结点
else
return p->rchild;
}
//输出后继序列
void InOrderNext(ThreadTree T){
for(ThreadTree p=FirstNode(T); p!=NULL; p=NextNode(p))
printf("%c ",p->data);
}
//找到以p为根的子树中,最后一个被中序遍历的结点
ThreadTree LastNode(ThreadTree p){
//循环找到最右下结点(不一定是叶结点)
while(p->rtag==0) p=p->rchild;
return p;
}
//在中序线索二叉树中找到结点p的前驱结点
ThreadTree PreNode(ThreadTree p){
if(p->ltag==0) //若p有左子树
return LastNode(p->lchild); //左子树中最右下的结点
else
return p->lchild;
}
//输出前驱序列
void InOrderPre(ThreadTree T){
for(ThreadTree p=LastNode(T); p!=NULL; p=PreNode(p))
printf("%c ",p->data);
}
//先序递归构建二叉树
int sc=0; //全局变量sc, 枚举串
ThreadTree CreateBiTree(char *s){ //s为先序遍历串
ThreadTree T;
if(s[sc]=='^') T=NULL;
else{
T=(ThreadTree)malloc(sizeof(ThreadNode));
T->data=s[sc++];
T->lchild=CreateBiTree(s); sc++;
T->rchild=CreateBiTree(s);
}
return T;
}
int main(){
char s[]="ABD^G^^E^^CF^^^";
ThreadTree T=CreateBiTree(s); //先序递归构建二叉树
CreateInThread(T); //建立中序线索二叉树
printf("输出中序的后继序列:"); InOrderNext(T);
printf("\n输出中序的前驱序列:"); InOrderPre(T);
return 0;
}