首页 > 其他分享 >1159 Structure of a Binary Tree + 根据前序和中序构建二叉树+ 层序遍历模板复习

1159 Structure of a Binary Tree + 根据前序和中序构建二叉树+ 层序遍历模板复习

时间:2023-05-03 17:44:16浏览次数:57  
标签:Binary str int 前序 tree pos 二叉树 key root

题目链接https://pintia.cn/problem-sets/994805342720868352/exam/problems/1478635126488367104

唉,今天的bug出在了下面这条语句。

if (tree[root_key].left * tree[root_key].right < 0) full_tree = false;

我写成了

full_tree = !(tree[root_key].left * tree[root_key].right < 0); // 这就会导致full_tree即便变成了false也有可能变回true。导致错判。

根据前序和中序构建二叉树

参考的柳神代码,灵活的点就在于,用下标表示数组区间,嗯,相比直接传数组的引用,轻了不少。

int build(int R, int start, int end, int fa) { // 1. post数组的最右边的位置;2. start, end : in数组的起始位置;3. 对于这题来说还需要记录父节点fa。
    if (start > end) return -1;
    int root_key = post[R], pos = start;
    while (in[pos] != root_key && pos < end) pos++;
    tree[root_key].level = tree[fa].level + 1;
    tree[root_key].fa = fa;
    tree[root_key].left = build(R - 1 - (end - pos), start, pos - 1, root_key); // 记住post的最后一个元素的下标一定要用 R 来相对计算,而不是只用 pos,不然在递归的过程中,即便前几层看不出什么,往后一定会发生错位。
    tree[root_key].right = build(R - 1, pos + 1, end, root_key);  // 下标的选择是经常容易出bug的,一定要想清楚
    if (tree[root_key].left * tree[root_key].right < 0) full_tree = false;
    return root_key;
}

题解代码:

#include<iostream>
#include<vector>
#include<string>
#include<queue>
using namespace std;
int n, m;
struct Node {
    Node() {
        fa = left = right = -1;
    }
    int level, fa, left, right;
} tree[1005];
bool full_tree = true;
int in[35], post[35], num1, num2;
int build(int R, int start, int end, int fa) { // 1. post数组的最右边的位置;2. start, end : in数组的起始位置;3. 对于这题来说还需要记录父节点fa。
    if (start > end) return -1;
    int root_key = post[R], pos = start;
    while (in[pos] != root_key && pos < end) pos++;
    tree[root_key].level = tree[fa].level + 1;
    tree[root_key].fa = fa;
    tree[root_key].left = build(R - 1 - (end - pos), start, pos - 1, root_key); // 记住post的最后一个元素的下标一定要用 R 来相对计算,而不是只用 pos,不然在递归的过程中,即便前几层看不出什么,往后一定会发生错位。
    tree[root_key].right = build(R - 1, pos + 1, end, root_key);  // 下标的选择是经常容易出bug的,一定要想清楚
    if (tree[root_key].left * tree[root_key].right < 0) full_tree = false;
    return root_key;
}
bool siblings(int a, int b) {
    return tree[a].fa == tree[b].fa;
}
bool same_level(int a, int b) {
    return tree[a].level == tree[b].level;
}
bool parent(int a, int b) {
    return tree[b].fa == a;
}
bool left_child(int a, int b) {
    return tree[b].left == a;
}
bool right_child(int a, int b) {
    return tree[b].right == a;
}
int main() {
    cin >> n;
    for (int i = 0; i < n; i++) cin >> post[i];
    for (int i = 0; i < n; i++) cin >> in[i];
    int root = post[n - 1];
    build(n - 1, 0, n - 1, 0);
    cin >> m;
    while (m--) {
        string str;
        cin >> str;
        if (str[0] == 'I') { 
            getline(cin, str);
            cout << (full_tree ? "Yes" : "No") << endl;
        } else {
            num1 = stoi(str);
            cin >> str;
            if (str[0] == 'a') {
                cin >> num2 >> str >> str;
                if (str[0] == 's') {
                    cout << (siblings(num1, num2) ? "Yes" : "No") << endl;
                } else {
                    getline(cin, str);
                    cout << (same_level(num1, num2) ? "Yes" : "No") << endl;
                }
            } else {
                cin >> str >> str;
                switch(str[1]) {
                    case 'o' : {
                        cout << (root == num1 ? "Yes" : "No") << endl;
                    } break;
                    case 'a' : {
                        cin >> str >> num2;
                        cout << (parent(num1, num2) ? "Yes" : "No") << endl;
                    } break;
                    case 'e' : {
                        cin >> str >> str >> num2;
                        cout << (left_child(num1, num2) ? "Yes" : "No") << endl;
                    } break;
                    case 'i' : {
                        cin >> str >> str >> num2;
                        cout << (right_child(num1, num2) ? "Yes" : "No") << endl;
                    } break;
                }               
            }
        }
    }
    return 0;
}

刚做的时候以为要用层序遍历,顺便复习一下吧。

层序遍历模板代码:

vector<vector<int>> level_order(Node *root) {
    vector<vector<int>> res;
    queue<Node *> q;
    if (root) q.push(root);
    while (q.size()) {
        int size = q.size();
        vector<int> v;
        for (int i = 0; i < size; i++) {
            Node *node = q.front();
            q.pop();
            // 上一排的元素依次出队
            v.push_back(node->val);
            // 下一排的节点全部入队
            if (node->left) q.push(node->left);
            if (node->right) q.push(node->right);
        }
        // 存入一排
        res.push_back(v);
    }
    return res;
}

标签:Binary,str,int,前序,tree,pos,二叉树,key,root
From: https://www.cnblogs.com/jby3303/p/17369175.html

相关文章

  • Codeforces 894D Ralph And His Tour in Binary Country
    预处理出对于\(u\)节点其子树内节点(包括\(u\))与\(u\)的距离,从小到大排序得到\(ds_u\)同时对\(ds_u\)进行前缀和处理\(dh_{u,i}=\sum\limits_{j=1}^{i}ds_{u,j}\)这样设\(tot\)为\(ds_u\)二分得到的\(ds_{u,i}\leh\)的右端点,也即为\(u\)子树内对答案有......
  • 【字节二面算法】NO662 二叉树最大宽度
    [字节二面算法]662.二叉树最大宽度给你一棵二叉树的根节点root,返回树的最大宽度。树的最大宽度是所有层中最大的宽度。每一层的宽度被定义为该层最左和最右的非空节点(即,两个端点)之间的长度。将这个二叉树视作与满二叉树结构相同,两端点间会出现一些延伸到这一层的n......
  • Java层序遍历打印二叉树(有Null值)
    publicclassSolution{publicstaticvoidmain(String[]args){Integer[]arr={3,9,20,null,null,15};//根据数组构造出二叉树TreeNodetreeNode=creatTreeNode(arr,0);//层序有Null值的打印二叉树printBin......
  • 线索化二叉树的递归算法
    //线索化二叉树的递归算法#include<stdio.h>#include<malloc.h>typedefstructBiTNode{intdata;structBiTNode*lchild,*rchild;//存储二叉树的左孩子和右孩子}BiTNode,*BiTree;typedefstructThreadNode{intdata;structThreadNode*......
  • Java根据Integer数组(有null值)递归构造二叉树
    二叉树:publicclassTreeNode{intval;TreeNodeleft;TreeNoderight;TreeNode(){}TreeNode(intval){this.val=val;}TreeNode(intval,TreeNodeleft,TreeNoderight){this.val=val;this.l......
  • 二叉树Binary Tree
    二叉树BinaryTree1.树的一些常用术语2.二叉树的概念树有很多种,每个节点最多只能有两个子节点的一种形式称为二叉树;二叉树的子节点分为左子节点和右子节点;以下三种均为二叉树:若该二叉树的所有叶子节点都在最后一层,且节点总数n==\(2^k\)-1,k为层数,则称为满二叉树......
  • 23-4-27--二叉树--玩转二叉树
    给定一棵二叉树的中序遍历和前序遍历,请你先将树做个镜面反转,再输出反转后的层序遍历的序列。所谓镜面反转,是指将所有非叶结点的左右孩子对换。这里假设键值都是互不相等的正整数。输入格式:输入第一行给出一个正整数N(≤30),是二叉树中结点的个数。第二行给出其中序遍历序列。第三行......
  • 实现二叉树结点的新建、查找、修改
     如果需要新建结点(例如往二叉树里面插入结点时,可使用下面的函数(返回类型是一个指向node的指针)node*newNode(intv){nodeNode=newnode;//申请一个node类型变量的地址空间Node->data=v;//结点权值为vNode->lchild=Node->rchild=NULL;//初始状态下无左右孩子retur......
  • 请用java写二叉树算法,实现添加数据形成二叉树功能,并以先序的方式打印出来....
    先转载过来以后再研究importjava.io.*;importjava.util.Stack;publicclassmyTest{privatemyTreetree;/***二叉树的插入,参数为(关键字,数据)***/publicvoidinsert(intkey,intdata......
  • SQL Injector - GET Manual Setup Binary Payload Attack
    bt5上操作:***********************************************************************Fast-Track-Anewbeginning...****Version:4.0.2......