本篇文章以及代码参考其他博主的内容增加自己的注释完成,仅供学习交流
#include<cstdio>
#include<iostream>
#include<queue> //引入stl中的队列
using namespace std;
typedef struct node{
char data; //二叉树节点的数据域用字母表示
node* lchild; //C++语言中结构体定义时无需给出struct关键字
node* rchild;
}node,*Bi;
typedef struct{
int lel; //指向当前处理的元素在层次序列中的位置
int inlow,inhigh; //中序序列的上下界
Bi parent; //层次序列中当前结点的双亲结点指针
int lr; //判断左右子树,1为左子树,2为右子树
}Sq;
//先序遍历二叉树
void preorder(Bi p)
{
if(p)
{
printf("%c ",p->data);
preorder(p->lchild);
preorder(p->rchild);
}
}
//依据二叉树的层次序列和中序序列以及给出序列节点数n,建立二叉树的先序序列
void Creat(Bi &bt,char lev[],char in[],int n)
{
Sq q;
queue <Sq> Q;
if(n<1)
bt=NULL; //二叉树为空
else
{
int i,s;
i=s=0; //s指向层次序列中当前处理的元素,i用来寻找当前处理的元素在中序序列中的位置
bt=new node;
bt->data=lev[0];
bt->lchild=bt->rchild=NULL;
while(in[i]!=lev[0])
i++;
if(i==0 && i==n-1) return ; //只有一个根节点
if(i==0) //没有左子树
{
bt->lchild=NULL;
q.lel=++s; //指向当前处理的元素在层次序列中的位置
q.inlow=i+1; //中序序列的上下界
q.inhigh=n-1;
q.lr=2; //判断左右子树,1为左子树,2为右子树
q.parent=bt; //层次序列中当前结点的双亲结点指针
Q.push(q);
}
else if(i==n-1) //没有右子树
{
bt->rchild=NULL;
q.lel=++s; //指向当前处理的元素在层次序列中的位置
q.inlow=0; //中序序列的上下界
q.inhigh=i-1;
q.lr=1; //判断左右子树,1为左子树,2为右子树
q.parent=bt;//层次序列中当前结点的双亲结点指针
Q.push(q);
}
else
{
q.lel=++s; q.inlow=0; q.inhigh=i-1; q.lr=1; q.parent=bt;
Q.push(q);
q.lel=++s; q.inlow=i+1; q.inhigh=n-1; q.lr=2; q.parent=bt;
Q.push(q);
}
while(!Q.empty())
{
q=Q.front(); Q.pop(); //取出队首元素
Bi fat=q.parent;
i=q.inlow;
while(in[i]!=lev[q.lel])
i++;
Bi p=new node;
p->data=lev[q.lel];
p->lchild=p->rchild=NULL;
if(q.lr==1)
fat->lchild=p;
else
fat->rchild=p;
if(i==q.inlow && i==q.inhigh) //叶子结点,无孩子
{
p->lchild=p->rchild=NULL;
continue;
}
else if(i==q.inlow) //没有左孩子
{
p->lchild=NULL;
q.lel=++s; q.inlow=i+1; q.parent=p; q.lr=2;
Q.push(q);
}
else if(i==q.inhigh) //没有右孩子
{
p->rchild=NULL;
q.lel=++s; q.inhigh=i-1; q.parent=p; q.lr=1;
Q.push(q);
}
else
{
int inhigh=q.inhigh; //备份一下
q.lel=++s; q.inhigh=i-1; q.parent=p; q.lr=1;
Q.push(q);
q.lel=++s; q.inlow=i+1; q.inhigh=inhigh; q.parent=p; q.lr=2;
Q.push(q);
}
}
}
}
int main()
{
int n;
node *B;
char in[50],lev[50];
printf("请输入结点个数\n");
cin>>n;
printf("请输入中序遍历和层次遍历\n");
getchar(); //缓冲换行符\n,避免gets()函数失效
gets(in); gets(lev);
Creat(B,lev,in,n);
printf("构造完成,输出先序序列\n");
preorder(B);
return 0;
}