问题描述
二叉树重建(根据后序和中序遍历序列获取先序遍历序列)
主要算法
先建树->先序遍历
建树算法:二叉树的后序遍历序列的最后一个元素是二叉树的根。根据这个元素结合中序遍历序列可以将二叉树划分为左子树、根、右子树。再通过后序遍历倒数第二个元素将右子树或者左子树(右子树为空的情况下)划分成更小的左子树、根、右子树。如此下去,逆序扫描后序遍历序列,不断的划分子树。
代码
/*
功能:二叉树重建(根据后序遍历和中序遍历获取二叉树的先序遍历)
作者:pussy
日期:2015-11-21
*/
# include<stdio.h>
# include<malloc.h>
# include<string.h>
# define MAX 100
char post[MAX];//存储后序遍历序列
int i;
//二叉树节点
typedef struct BiTNode{
char data;
struct BiTNode *lchild,*rchild;
}BiTNode,*BiTree;
//栈
typedef struct{
BiTree data[MAX];
int top;
}Stack;
void build(char in[],int left,int right,BiTree &T);
BiTree newnode(char c);
int getIndex(char in[],char c);
void InitStack(Stack &s);
int isFull(Stack s);
int isEmpty(Stack s);
int Push(Stack &s,BiTree t);
int Pop(Stack &s);
int getTop(Stack &s,BiTree &t);
void PreOrder(BiTree T,Stack s1);
int main()
{
printf("请依次输入二叉树的后序和中序遍历序列\n");
char in[MAX];
scanf("%s%s",post,in);
i=strlen(post)-1;
BiTree T=NULL;
Stack s1;
InitStack(s1);
build(in,0,strlen(in)-1,T);
printf("先序遍历序列为:\n");
PreOrder(T,s1);
printf("\n");
return 0;
}
void PreOrder(BiTree T,Stack s1)
{
Push(s1,T);
printf("%c",T->data);
BiTree t=T;
while(!isEmpty(s1))
{
while(t)
{
Push(s1,t->lchild);
if(t->lchild)
printf("%c",t->lchild->data);
t=t->lchild;
}
Pop(s1);
if(!isEmpty(s1))
{
getTop(s1,t);
Pop(s1);
Push(s1,t->rchild);
if(t->rchild)
printf("%c",t->rchild->data);
t=t->rchild;
}
}
}
//根据先序和中序遍历序列重建二叉树
void build(char in[],int left,int right,BiTree &T)
{
if(left>right)//空子树
{
//T=NULL;
return ;
}
else if(left==right)
{
T=newnode(post[i--]);//叶子节点
return ;
}
else
{
T=newnode(post[i]);
int r=getIndex(in,post[i--]);
build(in,r+1,right,T->rchild);
build(in,left,r-1,T->lchild);
}
}
//分配一个新的节点
BiTree newnode(char c)
{
BiTree t=(BiTree)malloc(sizeof(BiTNode));
t->data=c;
t->lchild=t->rchild=NULL;
return t;
}
//获取字符在字符串中的下标
int getIndex(char in[],char c)
{
int j;
for(j=0;j<strlen(in);j++)
{
if(in[j]==c)
return j;
}
return j;
}
//初始化栈
void InitStack(Stack &s)
{
s.top=0;
}
//判断栈是否满了,若是,则返回1,否则返回0.
int isFull(Stack s)
{
if(s.top>=MAX)
return 1;
else
return 0;
}
//判断栈是否为空,若是,返回1,否则返回0
int isEmpty(Stack s)
{
if(s.top==0)
return 1;
else
return 0;
}
//入栈,若成功,则返回1,否则返回0
int Push(Stack &s,BiTree t)
{
if(isFull(s))
return 0;
else
{
s.data[s.top]=t;
s.top++;
return 1;
}
}
//出栈,若出栈成功,则返回1,否则返回0
int Pop(Stack &s)
{
if(isEmpty(s))
return 0;
else
{
s.top--;
return 1;
}
}
//获得栈顶元素,成功返回1,失败返回0
int getTop(Stack &s,BiTree &t)
{
if(isEmpty(s))
return 0;
else
{
t=s.data[s.top-1];
return 1;
}
}