//二叉树--中序链式存储
//中序线索二叉树
#include <stdio.h>
#include <stdlib.h>
#define MAXSIZE 100
struct ThreadNode{
//数据域
int value;
//左孩子
struct ThreadNode *lChild;
//右孩子
struct ThreadNode *rChild;
//1--前驱结点 0--左孩子
int ltag;
//1--后继结点 0--右孩子
int rtag;
};
typedef struct ThreadNode ThreadNode;
typedef struct ThreadNode* ThreadTree;
/*
初始化tree
*/
ThreadTree* initTree(ThreadTree root){
root=NULL;
return root;
}
/*
构造树
*/
ThreadTree* constructTree(ThreadTree root){
ThreadNode *p11=(ThreadNode *)malloc(sizeof(ThreadNode));
(*p11).ltag=0;
(*p11).rtag=0;
(*p11).value=11;
(*p11).lChild=NULL;
(*p11).rChild=NULL;
ThreadNode *p12=(ThreadNode *)malloc(sizeof(ThreadNode));
(*p12).ltag=0;
(*p12).rtag=0;
(*p12).value=12;
(*p12).lChild=NULL;
(*p12).rChild=NULL;
ThreadNode *p5=(ThreadNode *)malloc(sizeof(ThreadNode));
(*p5).ltag=0;
(*p5).rtag=0;
(*p5).value=5;
(*p5).lChild=NULL;
(*p5).rChild=p11;
ThreadNode *p6=(ThreadNode *)malloc(sizeof(ThreadNode));
(*p6).ltag=0;
(*p6).rtag=0;
(*p6).value=6;
(*p6).lChild=p12;
(*p6).rChild=NULL;
ThreadNode *p7=(ThreadNode *)malloc(sizeof(ThreadNode));
(*p7).ltag=0;
(*p7).rtag=0;
(*p7).value=7;
(*p7).lChild=NULL;
(*p7).rChild=NULL;
ThreadNode *p2=(ThreadNode *)malloc(sizeof(ThreadNode));
(*p2).ltag=0;
(*p2).rtag=0;
(*p2).value=2;
(*p2).lChild=NULL;
(*p2).rChild=p5;
ThreadNode *p3=(ThreadNode *)malloc(sizeof(ThreadNode));
(*p3).ltag=0;
(*p3).rtag=0;
(*p3).value=3;
(*p3).lChild=p6;
(*p3).rChild=p7;
ThreadNode *p1=(ThreadNode *)malloc(sizeof(ThreadNode));
(*p1).ltag=0;
(*p1).rtag=0;
(*p1).value=1;
(*p1).lChild=p2;
(*p1).rChild=p3;
root=p1;
return root;
}
//指向当前被访问的结点
ThreadNode *q=NULL;
/*
创建中序线索二叉树
*/
void createInThread(ThreadTree root){
if(root!=NULL){
inThread(root);
if((*q).rChild==NULL){
(*q).rtag=1;
}
}
}
/*
中序线索二叉树
*/
void inThread(ThreadTree root){
ThreadNode *pre=NULL;
if(root!=NULL){
inThread((*root).lChild);
pre=q;
q=root;
if((*q).lChild==NULL){
(*q).lChild=pre;
(*q).ltag=1;
}
if(pre!=NULL&&(*pre).rChild==NULL){
(*pre).rChild=q;
(*pre).rtag=1;
}
inThread((*root).rChild);
}
}
/*
找到以p为根的子树中,第一个被中序遍历的结点
*/
ThreadNode* inFirstNode(ThreadNode *p){
//循环找到最左下结点(不一定是叶子结点)
while((*p).ltag==0){
p=(*p).lChild;
}
return p;
}
/*
中序线索二叉树中找到结点p的后继结点
*/
ThreadNode* inNextNode(ThreadNode *p){
//右子树中最左下结点
if((*p).rtag==0){
return inFirstNode((*p).rChild);
}else{
return (*p).rChild;
}
}
/*
对中序线索二叉树进行中序遍历(利用线索实现的非递归算法)
*/
void inOrder(ThreadTree root){
ThreadNode *p=inFirstNode(root);
for(;p!=NULL;p=inNextNode(p)){
printf("%d ",(*p).value);
}
}
/*
找到以p为根的子树中,最后一个被中序遍历的结点
*/
ThreadNode* inLastNode(ThreadNode *p){
//循环找到最右下结点(不一定是叶子结点)
while((*p).rtag==0){
p=(*p).rChild;
}
return p;
}
/*
中序线索二叉树中找到结点p的前驱结点
*/
ThreadNode* inPreNode(ThreadNode *p){
//左子树中最右下结点
if((*p).ltag==0){
return inLastNode((*p).lChild);
}else{
return (*p).lChild;
}
}
/*
对中序线索二叉树进行逆中序遍历
*/
void revInOrder(ThreadTree root){
ThreadNode *p=inLastNode(root);
for(;p!=NULL;p=inPreNode(p)){
printf("%d ",(*p).value);
}
}
int main(){
ThreadTree root;
root=initTree(root);
root=constructTree(root);
createInThread(root);
inOrder(root);
printf("\n");
revInOrder(root);
return 0;
}
08-29
4206
05-10
1807
10-29
284
10-30
525