题目要求:
typedef struct BTREE { char data; struct BTREE *left; struct BTREE *right; }BTNode,*BTree; 输入二叉树的先序和中序遍历结果,生成二叉树,然后后序输出结果 错误输入则输出error 例如 输入 A回车 A回车 输出 A 输入 ABC ABCD 输出 error
分析
一.
若给出二叉树的前序和中序,或者给出二叉树的后序和中序,可以还原出唯一的二叉树。但给出前序和后序不可以。
二.
前序序列的第一个元素是该二叉树的根结点,在中序序列中找到根结点的位置(下标),便可知道该二叉树的左右子树中各自结点的个数。
据此,可将前序序列分为:根结点+左子树+右子树,将中序序列分为:左子树+根结点+右子树。问题又转化为,根据左右子树的前序序列和中序序列,分别还原二叉树(左右子树)。
三.
代码:
#include <iostream>
#include <cstring>
using namespace std;
typedef struct node
{
char data;
int ltag,rtag;
struct node *lchild;
struct node *rchild;
}BTNode,*BTree;
class BiTree{
private:
BTNode* root;
public:
BiTree(char s1[],char s2[],int n);
~BiTree();
void visit();
void inThread(BTNode* p);
BTNode* next(BTNode* p);
private:
BTree Create(char s1[],char s2[],int first1,int end1,int first2,int end2);
void PostOrder(BTNode* p);
};
int main(int argc, const char * argv[]) {
char s1[100],s2[100];
cin>>s1;
cin>>s2;
int len1=(int)strlen(s1);
int len2=(int)strlen(s2);
if(len1!=len2){
cout<<"error";
}
else{
BiTree s(s1, s2, len1);
s.visit();
}
return 0;
}
BiTree::BiTree(char s1[],char s2[],int n){
root=Create(s1, s2, 0, n-1, 0,n-1);
}
BTree BiTree::Create(char s1[],char s2[],int first1,int end1,int first2,int end2){
BTNode *p;
if(first1>end1){
return NULL;
}
char ch=s1[first1];
int i,pos=first2;
for(i=first2;i<=end2;i++){
if(s2[i]==ch){
pos=i;
break;
}
}
if(ch!=s2[pos]){
cout<<"error";
exit(-1);
}
p=new BTNode;
p->data=s1[first1];
p->ltag=0;
p->rtag=0;
p->lchild=Create(s1, s2, first1+1, first1+pos-first2, first2, pos-1);
p->rchild=Create(s1, s2, first1+pos-first2+1, end1, pos+1, end2);
return p;
}
void BiTree::visit(){
PostOrder(root);
}
void BiTree::PostOrder(BTNode* p){
if(p==NULL){
return;
}
else{
PostOrder(p->lchild);
PostOrder(p->rchild);
cout<<p->data;
}
}
BiTree::~BiTree(){
BTNode* p,*q;
if(root==NULL){
return;
}
p=root;
while(p->lchild!=NULL){
p=p->lchild;
}
while(p->rchild!=NULL){
q=p;
p=next(p);
delete q;
}
delete p;
}
void BiTree::inThread(BTNode* p){
if(p==NULL)
return;
static BTNode* pre=NULL;
inThread(p->lchild);
if(p->lchild==NULL){
p->ltag=1;
p->lchild=pre;
}
if(pre!=NULL&&pre->rchild==NULL){
pre->rtag=1;
pre->rchild=p;
}
pre=p;
inThread(p->rchild);
}
BTNode* BiTree::next(BTNode* p){
BTNode* q;
if(p->rtag==1){
return p->rchild;
}
else{
q=p->rchild;
while(q->ltag==0){
q=q->lchild;
}
}
return q;
}
说明:
此处用了线索二叉树,因为析构函数不能够传参数,所以不能递归,为了更容易访问每个结点,将其线索化。
其实里面还有很多不完善的地方,但是交到oj系统已经可以满分了。