【码图】数据结构作业3——复原二叉树

题目要求:

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系统已经可以满分了。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值