zoukankan      html  css  js  c++  java
  • 基础练习之二叉树

    二叉树的构建与遍历

    利用几个题目来回顾下如何根据二叉树的不同遍历次序构建一棵树,之后再对这棵树进行相应的操作。

    1.sdut problem 1489 - 求二叉树的先序遍历

    题目链接:http://acm.sdut.edu.cn/sdutoj/problem.php?action=showproblem&problemid=1489

    题目大意

    根据二叉树的后序遍历与中序遍历,求先序遍历。

    题解

    根据两个顺序,可以递归的将一棵树建立,之后递归输出数的先序遍历。

    代码如下:

    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    using namespace std;
    const int maxn = 100;
    int t;
    char s1[maxn], s2[maxn];
    struct node {
        char key;
        node *lson, *rson;
        node():lson(NULL),rson(NULL){}
    };
    node* _build(node* p, int l, int r, int pos) {
        int i;
        bool flag = false;
        for(i = l; i <= r; i++) {
            if(s1[i] == s2[pos]) {
                flag = true;
                break;
            }
        }
        if(!flag)return NULL;
        p = new node();
        p->key = s1[i];
        p->lson = _build(p->lson, l, i-1, pos-1-(r-i));
        p->rson = _build(p->rson, i+1, r, pos-1);
        return p;
    }
    void _pre(node* p) {
        if(p != NULL) {
            printf("%c", p->key);
            _pre(p->lson);
            _pre(p->rson);
        }
    }
    int main() {
        while(~scanf("%d", &t)) {
            while(t--) {
                scanf("%s%s", s1, s2);
                int len = strlen(s1);
                node *root;
                root = _build(root, 0, len-1, len-1);
                _pre(root);
                printf("
    ");
            }
        }
        return 0;
    }
    

    2.PAT 天梯赛 L2-006 树的遍历

    题目链接:https://www.patest.cn/contests/gplt/L2-006

    题目大意

    根据二叉树的中序遍历与后序遍历,输出层次遍历序列。

    题解

    同样构建一棵树,利用BFS得到层次遍历。

    代码如下:

    #include<cstdio>
    #include<cstring>
    #include<queue>
    using namespace std;
    const int maxn = 35;
    int n;
    int s1[maxn],s2[maxn];
    struct node {
        int key;
        node *lson, *rson;
        node():lson(NULL),rson(NULL){}
    }*root;
    
    node* _build(node* p, int l, int r, int pos) {
        int i;
        bool flag = false;
        for(i = l; i <= r; i++) {
            if(s1[pos] == s2[i]) {
                flag = true;
                break;
            }
        }
        if(!flag) return NULL;
        p = new node();
        p->key = s1[pos];
        p->lson = _build(p->lson, l, i-1, pos-1-(r-i));
        p->rson = _build(p->rson, i+1, r, pos-1);
        return p;
    }
    void bfs() {
        queue<node*> q;
        q.push(root);
        int cnt = 0;
        while(!q.empty()) {
            node *p = q.front(); q.pop();
            if(cnt) printf(" ");
            cnt = 1;
            printf("%d", p->key);
            if(NULL != p->lson) {
                q.push(p->lson);
            }
            if(NULL != p->rson) {
                q.push(p->rson);
            }
        }
        printf("
    ");
    }
    int main() {
        while(~scanf("%d", &n)) {
            for(int i = 0; i < n; i++) {
                scanf("%d", &s1[i]);
            }
            for(int i = 0; i < n; i++) {
                scanf("%d", &s2[i]);
            }
            root = _build(root, 0, n-1, n-1);
            bfs();
        }
        return 0;
    }
    

    3.UVa problem 122 - Trees on the level

    题目链接:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=838&page=show_problem&problem=58

    题目大意

    输入一棵二叉树,每个节点都是按照从根节点到它的移动序列给出(数字表示节点的编号,L表示左,R表示右边)。现在根据给出的信息输出这棵树的层次遍历序列。

    题解

    按照给的节点,模拟建立一棵树。之后用一次BFS得到树的层次遍历。

    代码如下:

    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<vector>
    #include<queue>
    using namespace std;
    const int maxn = 300;
    char s[maxn];
    bool failed;
    vector<int> ans;
    struct Node {
        bool have_value;
        int v;
        Node *left, *right;
        Node():have_value(false),left(NULL),right(NULL){}
    }*root;
    
    void _build(int v, char *s) {
        Node *u = root;
        int len = strlen(s);
        for(int i = 0; i < len; i++) {
            if('L' == s[i]) {
                if(NULL == u->left) u->left = new Node();
                u = u->left;
            }else if('R' == s[i]) {
                if(NULL == u->right) u->right = new Node();
                u = u->right;
            }
        }
        if(u->have_value){
            failed = true;
            return ;
        }
        u->have_value = true;
        u->v = v;
    }
    
    bool read_input() {
        failed = false;
        root = new Node();
        while(true) {
            if(scanf("%s", s) != 1) return false;
            if(!strcmp(s, "()")) break;
            int v;
            sscanf(&s[1], "%d", &v);
            _build(v, s);
        }
        return true;
    }
    
    bool bfs() {
        ans.clear();
        queue<Node*> q;
        q.push(root);
        while(!q.empty()) {
            Node *u = q.front(); q.pop();
            if(!u->have_value) return false;
            ans.push_back(u->v);
            if(u->left != NULL) {
                q.push(u->left);
            }
            if(u->right != NULL) {
                q.push(u->right);
            }
        }
        return true;
    }
    int main() {
        while(read_input()) {
            if(!bfs()) failed = true;
            if(failed) {
                printf("not complete
    ");
            }else {
                for(int i = 0; i < ans.size(); i++) {
                    if(i) printf(" ");
                    printf("%d", ans[i]);
                }
                printf("
    ");
            }
        }
        return 0;
    }
    

    4.UVa problem 548 - Tree

    题目链接:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=838&page=show_problem&problem=489

    题目大意

    给一棵点带权的二叉树的后序遍历与中序遍历,找到一个叶子使得它到跟的路径上的权和最小,如果有多解,输出叶子权值最小的那个。

    题解

    构建二叉树,DFS递归的遍历这棵树,得到解。

    代码如下:

    #include<cstdio>
    #include<cstring>
    #include<sstream>
    #include<iostream>
    #include<cstdlib>
    using namespace std;
    const int maxn = 10000+10;
    const int inf = 0x3f3f3f3f;
    int inorder[maxn],postorder[maxn];
    int n, _min, ans;
    struct Node {
        int value;
        Node *lson, *rson;
        Node():lson(NULL),rson(NULL){}
    }*root;
    
    Node* _build(Node* p, int l, int r, int pos) {
        int i;
        bool flag = false;
        for(i = l; i <= r; i++) {
            if(postorder[pos] == inorder[i]) {
                flag = true;
                break;
            }
        }
        if(!flag) return NULL;
        p = new Node();
        p->value = postorder[pos];
        p->lson = _build(p->lson, l, i-1, pos-1-(r-i));
        p->rson = _build(p->rson, i+1, r, pos-1);
        return p;
    }
    
    void _find(Node *p, int sum) {
        if(NULL == p)return ;
        sum += p->value;
        if(NULL == p->lson && NULL == p->rson) {
            if(_min > sum) {
                _min = sum;
                ans = p->value;
            }else if(_min == sum) {
                ans = (ans > p->value ? p->value: ans);
            }
            return ;
        }
        _find(p->lson, sum);
        _find(p->rson, sum);
        return ;
    }
    
    bool read_input(int *a) {
        string line;
        if(!getline(cin, line)) return false;
        int x;
        n = 0;
        stringstream ss(line);
        while(ss >> x)a[n++] = x;
        return n>0;
    }
    
    int main() {
        while(read_input(inorder)) {
            read_input(postorder);
            root = _build(root, 0, n-1, n-1);
            _min = inf;
            ans = inf;
            _find(root, 0);
            printf("%d
    ", ans);
        }
        return 0;
    }
    

    参考资料

    Focus on Tech & Enjoy Life!

  • 相关阅读:
    XML和JSON优缺点
    JSON与XML优缺点对比分析
    json数据格式
    ajax 请求二进制流 图片
    常用网站
    Js setTimeout 用法
    js Indexof的用法
    02_虚拟机的安装和SecureCRT、FileZilla、Xmanage、UltraEdit工具的介绍
    01_Hadoop学习笔记内容说明
    sudoers文件设置sudo命令无密码(root密码)登录
  • 原文地址:https://www.cnblogs.com/yinzm/p/5517675.html
Copyright © 2011-2022 走看看