已知先序、中序遍历数组,求树结构的一种实现
先上一个图解
然后是代码部分 解释都已经写在注释里了,在code::block 17.12中可以正确运行。
#include <stdio.h>
#include <stdlib.h>
#define MAX 64
/**
伪代码:
start1=先序数列起点
start2=中序数列起点
len=传进来的数列长度
取先序start号数,这是这次循环的父节点
获取在中序中的编号find,这个编号以前的是左节点,以后的是右节点
分别计算左节点组和右节点组的数量
len1=find-start2
len2=len-len1
如果len1或len2=0,说明左节点或右节点为空
如果不为空,则令先序数组中左节点组的第一个和右节点组的第一个分别为父节点的左右儿子
分别把左右节点组递归进行
如果左右都为空,则到达叶节点 return
**/
typedef struct Bintree{
char data;
struct Bintree* Left;
struct Bintree* Right;
}Bintr;
typedef struct TraversalArray{
char* array1;//先序数组存储
char* array2;//中序数组存储
int arraysize;
Bintr* BintreeArray;//按先序建的树节点队列,最后建的树就在这里的第一个元素
}TraArr;
//找到一个项c在数列里的位置并返回
int GetPosition(char* array,char c){
for(int i=0;;i++){
if(array[i]==c){
//printf("i=%d\n",i);
return i;
}
if(array[i]=='\0'){
printf("未找到\n");
return -1;
}
}
}
//核心建树的部分,见伪代码
Bintr* MakeTree(TraArr* T, int start1, int start2,int len){
char c=T->array1[start1];//先序中取第一个数
int find=GetPosition(T->array2,c);//在中序中找到A
int len1=find-start2;//计算传到下一级的左儿子数组长度
int len2=len-len1-1;//计算传到下一级的右儿子数组长度
printf("此次的中序:");
PrintArray(T->array2,start2,start2+len);
printf("此次的先序:");
PrintArray(T->array1,start1,start1+len);
if(len1==0&&len2==0){//叶节点,左右儿子都为空
printf("叶节点\n");
return;
}
if(len1!=0){//左儿子不为空
T->BintreeArray[start1].Left=&T->BintreeArray[start1+1];
printf("%c是%c的左儿子\n",T->array1[start1+1],T->array1[start1]);
MakeTree(T,start1+1,start2,len1);
}
if(len2!=0){//右儿子不为空
T->BintreeArray[start1].Right=&T->BintreeArray[start1+len1+1];
printf("%c是%c的右儿子\n",T->array1[start1+len1+1],T->array1[start1]);
MakeTree(T,start1+len1+1,start2+len1+1,len2);
}
return T->BintreeArray;
}
//打印每次递归的数组部分,更方便查看过程
void PrintArray(char* array,int start,int end){
for(int i=start;i<end;i++){
printf("%c",array[i]);
}
printf("\n");
}
//初始化数据结构
void InitTraArr(TraArr* T){
T->arraysize=strlen(T->array1);
T->BintreeArray=malloc(T->arraysize*sizeof(Bintr));
for(int i=0;i<=T->arraysize;i++){
T->BintreeArray[i].data=T->array1[i];
T->BintreeArray[i].Right=NULL;
T->BintreeArray[i].Left=NULL;
}
}
//后序遍历(递归)
void Aft_read(Bintr* R){
if(R==NULL){
return -1;
}
Aft_read(R->Left);
Aft_read(R->Right);
printf("%c\n",R->data);
}
int main()
{
TraArr TwoArray;
TwoArray.array1="ABCDEFGH";//先序
TwoArray.array2="BDCEAFHG";//中序
InitTraArr(&TwoArray);
Bintr* tree=MakeTree(&TwoArray,0,0,TwoArray.arraysize);
Aft_read(tree);
}