二叉树的创建_大多数人都不会手写创建并遍历二叉树,一航这里帮你终结了

创建二叉树、遍历二叉树、二叉树的最近公共祖先任何疑问、意见、建议请公众号留言或联系qq474356284先序、后序创建二叉树先中后层序遍历二叉树二叉树的最近公共祖先   

输入格式:

创建二叉树时的输入:

    如序列:{1 2 -1 -1 3 -1 -1}表示1结点有2,3两个孩子,2,3结点没有孩子。

    如序列:{3 5 6 -1 -1 2 7 -1 -1 4 -1 -1 1 9 -1 -1 8 -1 -1}

039b47e7b2a9801065c353bdd5fc9c49.png

其中-1表示结点为空。

需注意:已知先中、中后序可确定唯一二叉树,先后序不能确定唯一二叉树。(这里指的是遍历后的序列,而不是这里输入时的序列,因为输入时的序列含有空节点,已经含有二叉树的所有信息)

输入样例:

先序创建二叉树:
1 2 -1 -1 3 -1 -1
3 5 6 -1 -1 2 7 -1 -1 4 -1 -1 1 9 -1 -1 8 -1 -1
后序创建二叉树:
-1 -1 2 -1 -1 3 1
-1 -1 6 -1 -1 7 -1 -1 4 2 5 -1 -1 9 -1 -1 8 1 3

求两节点最近的公共祖先:
2 3
5 1

输出样例:

先序:
1 2 3
中序:
2 1 3
后序:
2 3 1

先序:1 2 3中序:2 1 3后序:2 3 1

先序:
3 5 6 2 7 4 1 9 8中序:
6 5 7 2 4 3 9 1 8
后序:
6 7 4 2 5 9 8 1 3

最近公共祖先:
1
3

4cfd90f566c4477260eab53871fec815.gif
解决方法:

待补充。

2021校招金山云9.16笔试题最近公共祖先(须自己创建二叉树)

(1)代码实现:

#include #include #include #include #include #include #include #include using namespace std;//一航代码//树节点定义(此处与leetcode定义保持一致)struct TreeNode {    int val;    TreeNode* left;    TreeNode* right;    TreeNode(int x): val(x), left(NULL), right(NULL){}//初值列};//创建二叉树//先中->√    先后->×    中后->√class creat_tree {public:    //先序创建一棵树    void creatpre(TreeNode** root){        /*如序列:{1 2 -1 -1 3 -1 -1}表示1结点有2,3两个孩子,2,3结点没有孩子。          如序列:{3 5 6 -1 -1 2 7 -1 -1 4 -1 -1 1 9 -1 -1 8 -1 -1}*/        int val;        cin >> val;        if (val == -1)            root = nullptr;        else {            *root = new TreeNode(val);            creatpre(&((*root)->left));            creatpre(&((*root)->right));        }    }    //后序创建一棵树    void creatpost(TreeNode** root, vector<int>& t, bool flag){        /*如序列:{-1 -1 2 -1 -1 3 1}表示1结点有2,3两个孩子,2,3结点没有孩子。          如序列:{-1 -1 6 -1 -1 7 -1 -1 4 2 5 -1 -1 9 -1 -1 8 1 3}*/        int val;        char ch;        if (flag) { //flag标记第一次获取二叉树序列            while (cin >> val) {                t.push_back(val);                if ((ch = getchar()) == '\n')                    break;            }            flag = false;        }        static int count = t.size();        val = t[--count];        if (val == -1)            root = nullptr;        else {            *root = new TreeNode(val);            creatpost(&((*root)->right), t, flag);            creatpost(&((*root)->left), t, flag);        }    }};//先中后三种递归遍历方式class traversal_rec {public:    vector<int> ans;    vector<int> preorder(TreeNode* root)    {        if (root == NULL)            return ans;        ans.push_back(root->val);        preorder(root->left);        preorder(root->right);        return ans;    }    vector<int> inorder(TreeNode* root)    {        if (root == NULL)            return ans;        inorder(root->left);        ans.push_back(root->val);        inorder(root->right);        return ans;    }    vector<int> posorder(TreeNode* root)    {        if (root == NULL)            return ans;        posorder(root->left);        posorder(root->right);        ans.push_back(root->val);        return ans;    }};//先中后三种迭代遍历二叉树参考:https://mp.weixin.qq.com/s/WKg0Ty1_3SZkztpHubZPRgclass traversal_ite {public:    vector<int> res;                                //保存结果    vector<int> preorder(TreeNode* root)    {        stack call;                      //调用栈        if (root != nullptr)            call.push(root);                        //首先介入root节点        while (!call.empty()) {            TreeNode* t = call.top();            call.pop();                             //访问过的节点弹出            if (t != nullptr) {                if (t->right)                    call.push(t->right);            //右节点先压栈,最后处理                if (t->left)                    call.push(t->left);                call.push(t);                       //当前节点重新压栈(留着以后处理),因为先序遍历所以最后压栈                call.push(nullptr);                 //在当前节点之前加入一个空节点表示已经访问过了            } else {                                //空节点表示之前已经访问过了,现在需要处理除了递归之外的内容                res.push_back(call.top()->val);     // call.top()是nullptr之前压栈的一个节点,也就是上面call.push(t)中的那个t                call.pop();                         //处理完了,第二次弹出节点(彻底从栈中移除)            }        }        return res;    }    vector<int> inorder(TreeNode* root)    {        stack call;        if (root != nullptr)            call.push(root);        while (!call.empty()) {            TreeNode* t = call.top();            call.pop();            if (t != nullptr) {                if (t->right)                    call.push(t->right);                call.push(t);                       //在左节点之前重新插入该节点,以便在左节点之后处理(访问值)                call.push(nullptr);                 //nullptr跟随t插入,标识已经访问过,还没有被处理                if (t->left)                    call.push(t->left);            } else {                res.push_back(call.top()->val);                call.pop();            }        }        return res;    }    vector<int> postorder(TreeNode* root)    {        stack call;        if (root != nullptr)            call.push(root);        while (!call.empty()) {            TreeNode* t = call.top();            call.pop();            if (t != nullptr) {                call.push(t);                       //在右节点之前重新插入该节点,以便在最后处理(访问值)                call.push(nullptr);                 //nullptr跟随t插入,标识已经访问过,还没有被处理                if (t->right)                    call.push(t->right);                if (t->left)                    call.push(t->left);            } else {                res.push_back(call.top()->val);                call.pop();            }        }        return res;    }};//层序遍历二叉树class level_order {public:    vector<vector<int>> levelOrder(TreeNode* root)    {        queue que;        if (root != NULL)            que.push(root);        vector<vector<int>> result;        while (!que.empty()) {            int size = que.size();            vector<int> vec;            for (int i = 0; i < size; i++) {        // 这里一定要使用固定大小size,不要使用que.size(),因为que.size是不断变化的                TreeNode* node = que.front();                que.pop();                vec.push_back(node->val);                if (node->left)                    que.push(node->left);                if (node->right)                    que.push(node->right);            }            result.push_back(vec);        }        return result;    }};// p结点与q结点的最近公共祖先TreeNode* lowc(TreeNode* root, int p, int q){    if (root == nullptr)        return 0;    if (root->val == p || root->val == q)        return root;    TreeNode* rleft = lowc(root->left, p, q);    TreeNode* rright = lowc(root->right, p, q);    if (rleft != nullptr && rright != nullptr)        return root;    else if (rright != nullptr)        return rright;    else        return rleft;    return nullptr;}int main(){    creat_tree creat;    TreeNode* root;    //先序创建二叉树    creat.creatpre(&root);    //后序创建二叉树    // vector tree;    // creat.creatpost(&root, tree, true);    traversal_rec rec;    vector<int> res = rec.preorder(root);    // vector res = rec.inorder(root);    // vector res = rec.posorder(root);    traversal_ite ite;    // vector res = ite.preorder(root);    // vector res = ite.inorder(root);    // vector res = ite.postorder(root);    for (int i = 0; i < (int)res.size(); i++) {//注意最后一个节点输出后面有空格        cout << res[i] << " ";    }    cout << endl;    // level_order level;                      //层序输出    // vector> res = level.levelOrder(root);    // for(int i = 0;i < (int)res.size();i++){    //     for(int j = 0;j < (int)res[i].size();j++){    //         cout << res[i][j] << " ";    //     }    // }    //求二叉树结点p,q最近的公共祖先    int p, q;    cin >> p >> q;    TreeNode *t = lowc(root, p, q);    cout << t->val << endl;    return 0;}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/430951.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

zookeeper 密码_阿里资深JAVA架构带你深度剖析dubbo和zookeeper关系

为什么要用dubbo&#xff1f;当网站规模达到了一定的量级的时候&#xff0c;普通的MVC框架已经不能满足我们的需求&#xff0c;于是分布式的服务框架和流动式的架构就凸显出来了。单一应用架构当网站流量很小时&#xff0c;只需一个应用&#xff0c;将所有功能都部署在一起&…

nw.js FrameLess Window下的窗口拖拽与窗口大小控制

nw.js FrameLess Window下的窗口拖拽与窗口大小控制 很多时候&#xff0c;我们觉得系统的Frame框很难看&#xff0c;于是想自定义。 自定义Frame的第一步是在package.config文件中将frame选项设置为false。 { "name": "1", "main": "index.…

linux 文件重命名_如何在 Linux 上重命名一组文件 | Linux 中国

要用单个命令重命名一组文件&#xff0c;请使用 rename 命令。它需要使用正则表达式&#xff0c;并且可以在开始前告诉你会有什么更改。-- Sandra Henry-stocker几十年来&#xff0c;Linux 用户一直使用 mv 命令重命名文件。它很简单&#xff0c;并且能做到你要做的。但有时你需…

oracle插入性能优化,Oracle-insert性能优化

看见朋友导入数据&#xff0c;花了很长时间都没完成&#xff01;其实有很多快速的方法&#xff0c;整理下&#xff01; 向表中插入数据有很多办法,但是方法不同&#xff0c;性能差别很看见朋友导入数据&#xff0c;&#xff0c;花了很长时间都没完成&#xff01;其实有很多快速…

dba_segments和dba_tables的不同

create table tset as select * from dba_objects; select count(*) from tset; select table_name,blocks,empty_blocks from dba_tables where table_name’TSET’; select segment_name,bytes,blocks,extents from dba_segments where segment_name’TSET’; 问题来了&#…

微博air客户端_打磨近十年,接近「完美」的 macOS 第三方微博客户端:Maipo

2020年11月13日&#xff0c;macOS Big Sur正式推送当天&#xff0c;Maipo for 微博也迎来了4.0.0大版本更新。从Weibo for Mac&#xff08;2011年&#xff09;、WeiboX&#xff08;2014年&#xff09;到Maipo&#xff08;2017年&#xff09;&#xff0c;跨度近十年&#xff0c;…

输入框联动查询

目的&#xff1a;类似于百度的搜索联动&#xff0c;输入前面的几个字&#xff0c;查询出可能的结果供用户选择&#xff0c;如下&#xff1a; html部分&#xff1a;在“中”这个输入框下面隐藏一个ul属性&#xff0c;例如: <ul class"am-padding-left-0 uhide" id&…

LoadRunner函数

一、基础函数简介 在VU左边导航栏中&#xff0c;有三个LoadRunner框架函数&#xff0c;分别是vuser_init()、Action()、vuser_end()。这三个函数存在于任何Vuser类型的脚本中。 vuser_init:虚拟用户的初始化函数&#xff0c;一般将用户初始化的操作放在这里&#xff0c;如登录操…

TPLink 备份文件bin文件解析

TPLink 路由器备份文件bin文件 测试路由器 WR885&#xff0c;备份文件加密方式DES&#xff0c;密钥&#xff1a;478DA50BF9E3D2CF linux端&#xff1a; openssl enc -d -des-ecb -nopad -K 478DA50BF9E3D2CF -in config.bin python&#xff1a; python默认没有安装crypto需要自…

linux的文件搜索命令,Linux文件搜索命令find的用法 | 术与道的分享

不管在Windows还是Linux中&#xff0c;最重要的问题不是说你能搜索到这个文件&#xff0c;而是最好少用搜索&#xff0c;应该是你在整个服务器的规划里面&#xff0c;把所以的文件目录规划的很好。就像如果你在家里找衣服&#xff0c;如果不是你乱扔&#xff0c;就不可能花费太…

vue v-if判断数组元素的值_Vue项目上线做的一些基本优化

前言本文主要是做一个Vue性能优化的帖子&#xff0c;做一个参考文档&#xff0c;对以后项目上线做一些集合文档。如果对各位在项目优化时&#xff0c;做一个文档参照。开发过程在开发项目的时候&#xff0c;就要注意项目的一些小技巧&#xff0c;下面我就罗列一些经常用到的优化…

BZOJ 4000: [TJOI2015]棋盘( 状压dp + 矩阵快速幂 )

状压dp, 然后转移都是一样的, 矩阵乘法快速幂就行啦. O(logN*2^(3m)) ---------------------------------------------------------------------------------------------#include<cstdio>#include<cstring>#include<algorithm>using namespace std;#define …

linux传文件file,linux文件的传输与压缩快速入门

scp --- 用于远程拷贝文件上传文件scp file userip:/file下载文件scp userip:/file filersync --- 远程同步&#xff0c;速度块&#xff0c;默认会忽略&#xff0c;文件属性&#xff0c;链接文件&#xff0c;设备文件-r --- 同步目录-p --- 同步权限-o --- 同步文件所有人-g --…

delphi 中如果不进行 closehandle 会怎么样_心理学:当你迷茫了,请坚持做三件事,你的未来会越来越好...

我们总是这样激励自己&#xff1a;未来是美好的。但是&#xff0c;生活不可能处处如意&#xff0c;人的一生也难以风平浪静&#xff0c;有巅峰就有低谷&#xff0c;有明朗就有迷茫。或是找不到未来发展的方向&#xff0c;或是事业、生活遭受了重大挫折&#xff0c;我们每个人都…

随笔2 PAT1001.A+B Format (20)

1001.AB Format(20) 题目链接 1001.AB Format (20) C 代码 第一次使用markdown&#xff0c;还不是很习惯&#xff0c;现在努力的在适应它 首先这道题我们很容易就可以读懂题意&#xff0c;就是简单的ab&#xff0c;只不过要求我们在输出sum的时候处理一下数字的格式。那么我的做…

mybatis传递多个参数_深入浅出MyBatis:MyBatis解析和运行原理

原文&#xff1a;https://juejin.im/post/5abcbd946fb9a028d1412efc本篇文章是「深入浅出MyBatis&#xff1a;技术原理与实践」书籍的总结笔记。上一篇介绍了反射和动态代理基础&#xff0c;主要是为本篇文章做个铺垫&#xff0c;反射使配置和灵活性大大提高&#xff0c;可以给…

linux ps 进程组,linux进程管理(2)---进程的组织结构

一、目的linux为了不同的进程管理目的&#xff0c;使用了不同的方法组织进程之间的关系&#xff0c;为了体现父子关系&#xff0c;使用了“树形”图&#xff1b;为了对同一信号量统一处理&#xff0c;使用了进程组&#xff1b;为了快速查找某个进程&#xff0c;使用了哈希表&am…

统计建模与r软件_【统计建模与R软件笔记】008 描述统计量(1)

今天我们开始来学习描述统计量吧&#xff01;位置的度量位置的度量就是用来描述定量资料的集中趋势的统计量&#xff0c;常用的有均值、众数、中位数、百分位数等。1.均值 mean( )形式&#xff1a;mean(x, trim 0, na.rm FALSE)x 是对象(如向量、矩阵、数组或数据框)trim 是计…

npm环境安装linux,Node.js环境在linux上的部署教程

我们以centOS为例来说说如何部署node.js环境一 打开centos,然后开始下载node.js包curl --silent --location https://rpm.nodesource.com/setup_6.x | bash -yum -y install nodejs二 安装gcc环境yum install gcc-c make安装完成!三 安装nodejs的npm,这是一个包程序工具,类似于…

Nancy跨平台开发总结(三)发布到Jexus Web服务器

在Centos7上安装Mono yum install yum-utils rpm --import "http://keyserver.ubuntu.com/pks/lookup?opget&search0x3FA7E0328081BFF6A14DA29AA6A19B38D3D831EF" yum-config-manager --add-repo http://download.mono-project.com/repo/centos/ yum install m…