zoukankan      html  css  js  c++  java
  • 建树

    先序中序建树

    已知前序(先序)与中序输出后序:
    前序:1, 2, 3, 4, 5, 6(根左右)
    中序:3, 2, 4, 1, 6, 5(左根右)
    分析:因为前序(根左右)最先出现的总是根结点,所以令root为前序中当前的根结点下标(并且同时把一棵树分为左子树和右子树)。start为当前需要打印的子树在中序中的最左边的下标,end为当前需要打印的子树在中序中最右边的下标。递归打印这棵树的后序,递归出口为start > end。i为root所表示的值在中序中的下标,所以i即是分隔中序中对应root结点的左子树和右子树的下标。
    先打印左子树,后打印右子树,最后输出当前根结点pre[root]的值。
    输出的后序应该为:3, 4, 2, 6, 5, 1(左右根)

    #include <cstdio>
    using namespace std;
    int pre[] = {1, 2, 3, 4, 5, 6};
    int in[] = {3, 2, 4, 1, 6, 5};
    void post(int root, int start, int end) {
        if(start > end) 
            return ;
        int i = start;
        while(i < end && in[i] != pre[root]) i++;
        post(root + 1, start, i - 1);
        post(root + 1 + i - start, i + 1, end);
        printf("%d ", pre[root]);
    }
    
    int main() {
        post(0, 0, 5);
        return 0;
    }
    TreeNode* buildTree(int root, int start, int end) {
        if(start > end) return NULL;
        int i = start;
        while(i < end && in[i] != pre[root]) i++;
        TreeNode* t = new TreeNode();
        t->left = buildTree(root + 1, start, i - 1);
        t->right = buildTree(root + 1 + i - start, i + 1, end);
        t->data = pre[root];
        return t;
    }

     

    后序中序建树

    PAT 1127. ZigZagging on a Tree (30)-甲级

    题目大意:给出一个树的中序和后序遍历结果,求它的Z字型层序遍历,也就是偶数层从右往左,奇数层从左往右遍历~
    分析:分为3步:1.根据中序和后序建树 保存在tree二维数组中,比如:tree[i][0] = val表示post[i]的左孩子是post[val],tree[i][1] = val表示post[i]的右孩子是post[val]~
    2.进行广度优先搜索,将树从根结点开始所有结点层序遍历,保存在result二维数组中,比如:result[i]保存第i层所有结点的序列~
    3.进行z字型输出,根据当前层号的奇偶性分别从左往右、从右往左遍历输出~

    1. dfs:因为post(后序)是按照左、右、根的顺序遍历的,所以从右往左,最右边的肯定是根结点~所以postRight是当前子树的根结点的下标,将它的赋值给index,并继续dfs tree[index][0]和tree[index][1]~
    根据post[postRight]的结点在in里面的下标位置i,可以得到i的左边是左子树,即inLeft 到 i - 1,右边是右子树:i + 1 到 inRight。而对于post来说,根据左子树的结点个数i - inLeft可以得到[postLeft, postLeft + (i - inLeft) - 1]是post中左子树的范围,[postLeft + (i - inLeft), postRight - 1]是post中右子树的范围~
    2.广度优先搜索,采用队列q,q中保存的是node结点,node.index表示当前节点在post中的下标,node.depth表示当前结点在树中的层数~

    3.当 i % 2 == 0的时候倒序输出,否则正序输出~

    #include <iostream>
    #include <vector>
    #include <queue>
    using namespace std;
    vector<int> in, post, result[35];
    int n, tree[35][2], root;
    struct node {
        int index, depth;
    };
    void dfs(int &index, int inLeft, int inRight, int postLeft, int postRight) {
        if (inLeft > inRight) return;
        index = postRight;
        int i = 0;
        while (in[i] != post[postRight]) i++;
        dfs(tree[index][0], inLeft, i - 1, postLeft, postLeft + (i - inLeft) - 1);
        dfs(tree[index][1], i + 1, inRight, postLeft + (i - inLeft), postRight - 1);
    }
    void bfs() {
        queue<node> q;
        q.push(node{root, 0});
        while (!q.empty()) {
            node temp = q.front();
            q.pop();
            result[temp.depth].push_back(post[temp.index]);
            if (tree[temp.index][0] != 0)
                q.push(node{tree[temp.index][0], temp.depth + 1});
            if (tree[temp.index][1] != 0)
                q.push(node{tree[temp.index][1], temp.depth + 1});
        }
    }
    int main() {
        cin >> n;
        in.resize(n + 1), post.resize(n + 1);
        for (int i = 1; i <= n; i++) cin >> in[i];
        for (int i = 1; i <= n; i++) cin >> post[i];
        dfs(root, 1, n, 1, n);
        bfs();
        printf("%d", result[0][0]);
        for (int i = 1; i < 35; i++) {
            if (i % 2 == 1) {
                for (int j = 0; j < result[i].size(); j++)
                    printf(" %d", result[i][j]);
            } else {
                for (int j = result[i].size() - 1; j >= 0; j--)
                    printf(" %d", result[i][j]);
            }
        }
        return 0;
    }
  • 相关阅读:
    T- SQL性能优化详解
    C# 路径
    sql2000无法打开1433端口及解决方法
    MySQL:创建、修改和删除表
    mysql 授权 打开全部
    Mvc多级Views目录 asp.net mvc4 路由重写及 修改view 的寻找视图的规则
    asp.net 捕获全局未处理异常的几种方法
    无线路由器WDS设置方法图解_无线桥接设置
    100个直接可以拿来用的JavaScript实用功能代码片段
    ocx控件针对网页刷新和关闭分别进行区分处理
  • 原文地址:https://www.cnblogs.com/smallhester/p/13368045.html
Copyright © 2011-2022 走看看