题目:1385 由前序和中序构建二叉树

http://ac.jobdu.com/problem.php?pid=1385


蛮怀旧的题目,记得大一就见过一直没做过,没难度,纯小心吧。

类似的是有中序和后续构建二叉树。比如http://www.cnblogs.com/kaituorensheng/p/3788533.html

思路很简单 递归构造:

#include <cstdio>
#include <cstring>
#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;


const int SIZE = 1000+10;
struct Node{
    int v;
    Node *left;
    Node *right;
    Node(){
        v = -1;
        left = right = NULL;
    }
    Node(int val, Node *l, Node *r){
        v = val;
        left = l;
        right = r;
    }
};

int n;
int head[SIZE],mid[SIZE];
int flag,getNode;

Node* buildTree(int headptr, int midleft, int midright){
    /*cout << "*********" << endl;
    cout << "head=" << head[headptr] << endl;
    cout << "midleft=" << midleft << endl;
    cout << "midright=" << midright << endl;*/

    Node *father = new Node();
    int pos=-1;
    if(midleft == midright){
        if(head[headptr] == mid[midleft]){
            father->left = father->right = NULL;
            father->v = head[headptr];
            getNode++;
            return father;
        }else{
            return NULL;
        }
    }
    if(midleft > midright)return NULL;
    for(int i=midleft;i<=midright;i++){
        if(head[headptr] == mid[i])
            pos = i;
    }
    if(pos == -1)return NULL;
    int hasleft=0;//,hasright=0;
    if(pos == midleft){//意味着左子树为空
        father->left = NULL;
    }else{
        hasleft = 1;
        father->left = buildTree( headptr+1 , midleft, pos-1);
        if(father->left == NULL)return NULL;
    }
    if(pos == midright){
        father->right = NULL;
    }else{
        if(hasleft == 1){
            //左子树结点个数 pos-midleft
            father->right = buildTree(headptr+pos-midleft+1, pos+1, midright);
        }else{
            father->right = buildTree(headptr+1, pos+1, midright);
        }
        if(father->right == NULL)return NULL;
    }
    father->v = head[headptr];

    getNode++;
    return father;
}

/*void print(Node *nod){
    if(flag)putchar(' ');
    else flag=1;
    printf("%d", nod->v);
}*/

void print(Node *nod){
    //if(flag)putchar(' ');
    //else flag=1;
    printf("%d ", nod->v);
}

void sear(Node *father){
    //if(father->left == NULL && father->right == NULL){//叶子
        //print(father);
    //}
    if(father->left)sear(father->left);
    if(father->right)sear(father->right);
    print(father);
}

int main(){
    //freopen("06.txt", "r", stdin);
    int in;
    while(~scanf("%d", &n)){
        flag = getNode = 0;
        for(int i=0;i<n;i++){
            scanf("%d", &in);
            head[i] = in;
        }
        for(int i=0;i<n;i++){
            scanf("%d", &in);
            mid[i] = in;
        }
        Node *ancestor = buildTree(0, 0, n-1);
        if(ancestor == NULL || getNode != n){
        //if(ancestor == NULL ){
            printf("No\n");
        }else{
            sear(ancestor);
            printf("\n");
        }
        //cout << getNode << endl;

    }
    return 0;
}


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值