【无标题】面试常考算法(3):二叉树遍历(创建、遍历、销毁)

news2024/10/7 16:16:09

这部分不够熟悉的话,面试直接递归就行。不过实际中虽然递归在某些情况下可以提供简洁和优雅的解决方案,但可能占用大量的内存空间和导致额外时间开销,所以还是尽量使用非递归。因为每次递归调用时,函数的局部变量和参数都需要在栈上创建新的实例,这可能导致栈溢出或耗尽系统资源,尤其是当递归深度很大时。而且递归调用的开销包括函数调用、堆栈帧的创建和销毁等,大规模问题上使用递归可能导致时间性能下降

目录

  • 二叉树中序遍历

对于其他的遍历,只需要画个树写写递归伪代码,和

二叉树中序遍历

  给定一个二叉树的根节点root,返回它的中序遍历(“左根右”)结果。
  数据范围: 树上节点数满足 0 ≤ n ≤ 1000 0 \leq n \leq 1000 0n1000 ,树上每个节点的值满足 − 1000 ≤ v a l ≤ 1000 -1000 \leq v a l \leq 1000 1000val1000
  要求:空间复杂度 O ( n ) O(n) O(n) ,时间复杂度 O ( n ) O(n) O(n)

树节点:struct类型数据有聚合初始化(Aggregate initialization)、默认成员初始化和成员初始化列表(Member initialization list)等初始化方法,这里自定义构造函数以便使用成员初始化列表初始化

struct TreeNode {
    int val;
    struct TreeNode* left;
    struct TreeNode* right;
    TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}  //自定义构造函数以便使用成员初始化列表初始化
};
}

创建树和销毁树:

//递归法构建二叉树
int n; 
TreeNode* creatTree(vector<int> nums, int index) {
    // 二叉树结点x(x指该节点在C++数组中的索引位置)的左孩子在C++数组中的位置等于 2x+1 ,右孩子等于 2x+2 。
    if (nums[index] == '#')
        return nullptr;

    //创建新结点
    TreeNode* root= new TreeNode(nums[index]);
    printf("The value is %d \n", nums[index]);


    //设置左右指针
    if (index * 2+1 <= n)
        root->left = creatTree(nums, index * 2+1);	//找到左孩子
    else
        root->left = nullptr;
    if (index * 2 + 2 <= n)
        root->right = creatTree(nums, index * 2 + 2);	//找到右孩子
    else
        root->right = nullptr;

    return root;
}

// 注意创建树后不用了需要销毁,这里得手动释放空间
void destroyTree(TreeNode* node) {
    if (node == nullptr) {
        return;
    }

    destroyTree(node->left);
    destroyTree(node->right);

    printf("destroy node value is %d \n", node->val);
    delete node;
}

两种实现中序遍历的方法:利用栈非递归,递归

vector<int> inorderTraversal(TreeNode* root) {  //非递归方法
    vector<int> res;  // 存放中序遍历的输出值
    stack<TreeNode*> st;  // 栈中存放结点
    TreeNode* p = root;
    while (!st.empty() || p)  // p等于空说明根节点为空或者到了叶子节点的某个空子节点
    {// 循环条件为 【st非空 或者 p指向确定对象时(使用指针变量进行条件判断时,当指针变量为nullptr时,条件判断为假)】
        // 终止条件为 【st为空,且p等于nullptr】
        while (p)                //一直沿左子树向下
        {
            st.push(p);  // 由于st是栈,父节点先进入,后出
            p = p->left;
        }
        TreeNode* tt = st.top();   //到达叶子节点的某个空子节点,返回
        st.pop();
        res.push_back(tt->val);
        p = tt->right;  // 去检查右节点
    }
    return res;
}

void inorder(vector<int>& res, TreeNode* root) {
    //遇到空节点则返回
    if (root == NULL)
        return;
    //先遍历左子树
    inorder(res, root->left);
    //再遍历根节点
    res.push_back(root->val);
    //最后遍历右子树
    inorder(res, root->right);
}

vector<int> inorderTraversal2(TreeNode* root) {
    vector<int> res;
    //递归中序遍历
    inorder(res, root);
    return res;
}

main函数测试:

int main() {
    // 创建一颗树{1,2,#,#,3}
    vector<int> nums = { 1,2,'#','#',3 };
    n = nums.size();
    TreeNode* root = creatTree(nums, 0);
    vector<int> Non_recursice_res = inorderTraversal(root);
    cout << "非递归中序遍历:" << ' ';
    for (auto& element : Non_recursice_res) {
        std::cout << element << " ";
    }
    std::cout << std::endl;
    vector<int> recursice_res = inorderTraversal(root);
    cout<< "递归中序遍历:" << ' ';
    for (auto& element : recursice_res) {
        std::cout << element << " ";
    }
    std::cout << std::endl;
    destroyTree(root);
}

测试结果:
在这里插入图片描述

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

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

相关文章

迭代器模式(十九)

相信自己&#xff0c;请一定要相信自己 上一章简单介绍了访问者模式(十八), 如果没有看过, 请观看上一章 一. 迭代器模式 引用 菜鸟教程里面迭代器模式介绍: https://www.runoob.com/design-pattern/iterator-pattern.html 迭代器模式&#xff08;Iterator Pattern&#xff…

实战:私有化部署ngin+文件步骤记录

这里写目录标题 背景准备总结 背景 出差到某国企进行私有化部署&#xff0c;一波三折。没想到是那种最麻烦的部署&#xff0c;导入文件需要刻光盘&#xff0c;进入电脑房需要上交手机&#xff0c;不允许有人以及拍摄设备&#xff0c;内部有监控摄像头。 有问题怎么办&#xf…

SYSU程设c++(第十六周)

set set<int> st; 会自动排序升序 如果降序可以set<int, greater<int>> s; map map<string,int> m; 会按键进行升序 m["uiui"]100; map<string,int>::iterator it; for(itm.begin();it!m.end();it){ cout<<"键&qu…

Spark大数据处理学习笔记(3.3)掌握RDD分区

该文章主要为完成实训任务&#xff0c;详细实现过程及结果见【http://t.csdn.cn/OmCQ8】 文章目录 一、概念二、自定义分区器2.1 提出问题2.2 解决问题1. 准备数据文件2. 新建科目分区器3. 测试科目分区器 三、课后作业 一、概念 在Spark中&#xff0c;RDD&#xff08;弹性分布…

长文|基于Zabbix的可观测性监控

01 可观测性与可观测性监控 02 基于ZABBIX的可观测性监控 03 可观测性监控的探索 ——王小东&#xff0c;多年运维老兵&#xff0c;《nginx应用与运维实战》作者 本文整理自王小东在2022Zabbix峰会演讲分享。ppt可在公众号后台回复“ppt"。 1、可观测性与可观测性监控…

拷贝构造函数

拷贝构造函数 以值传递的方式调用函数时&#xff0c;如果实参为对象&#xff0c;会调用拷贝构造函数。函数以值的方式返回对象时&#xff0c;可能会调用拷贝构造函数&#xff08;VS会调用&#xff0c;Linux不会&#xff0c;g编译器做了优化&#xff09; 类似于构造函数和析构函…

Python控制流程盘点及高级用法、神秘技巧大揭秘!

在这篇文章中我们将全面深入地介绍 Python 的控制流程&#xff0c;包括条件语句、循环结构和异常处理等关键部分&#xff0c;尤其会将列表解析、生成器、装饰器等高级用法一网打尽。此外&#xff0c;我还将分享一些独特的见解和研究发现&#xff0c;希望能给你带来新的启发。文…

让你不再疑惑图片翻译怎么弄

你是否曾遇到过在阅读外语文章或资料时&#xff0c;遇到了图片上的文字无法翻译的困扰&#xff1f;别担心&#xff0c;如果你还不知道如何翻译图片上的文字的话&#xff0c;接下来我将教你三种图片翻译的实用小技巧&#xff0c;一起来看看吧。 翻译图片的实用方法一&#xff1a…

Python语法基础01(列表,元组,字典)

Python基础语法 变量的命名与使用 变量名只能包含字母、数字和下划线&#xff0c;只能以字母和下划线为开头不能包含空格不能使用python保留字 列表&#xff0c;元组&#xff0c;字典 列表 定义列表(元素之间可以没有任何关系)&#xff1a;[] 例如 fruits["apple&qu…

oracle如何才能卸载干净

windows系统下oracle如何才能卸载干净 1.关闭oracle所有的服务。2.删除注册表中相关信息3.删除注册表中相关Oracle安装信息4.删除注册的oracle事件日志5.删除环境变量path中关于oracle的内容6.重新启动操作系统7.删除Oracle_Home下的所有数据8.删除oracle安装目录。9.删除开始菜…

灰度图像逻辑运算之逻辑或

目录 note code test note out max(x1,x2) code void img_logic_or_fun(uchar& in1, uchar& in2, uchar& out) {out in1 > in2 ? in1 : in2; } void img_logic_or(Mat& src1, Mat& src2, Mat& res) {if (src1.size() ! src2.size()) {retur…

基于html+css的图展示128

准备项目 项目开发工具 Visual Studio Code 1.44.2 版本: 1.44.2 提交: ff915844119ce9485abfe8aa9076ec76b5300ddd 日期: 2020-04-16T16:36:23.138Z Electron: 7.1.11 Chrome: 78.0.3904.130 Node.js: 12.8.1 V8: 7.8.279.23-electron.0 OS: Windows_NT x64 10.0.19044 项目…

【微信支付】微信v3支付案例,SpringBoot集成IJPay实现微信v3支付

前言 这篇文章主要实现一下通过IJPay来实现微信v3支付案例&#xff0c;本篇文章使用的是JSAPI即小程序支付 IJPay码云仓库&#xff1a;https://gitee.com/javen205/IJPay/tree/dev IJPay官方文档&#xff1a;https://javen205.gitee.io/ijpay/ 准备工作 导入依赖 <depen…

Python学习48:简易英汉字典

类型&#xff1a;字典‪‬‪‬‪‬‪‬‪‬‮‬‪‬‫‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‭‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‮‬‪‬‪‬‪‬‪‬‪‬‮‬‭‬‫‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‭‬‫‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‪‬ 描述‪‬‪‬…

SpringBoot+Mybatis 实现长字符串保存和更新

数据库字段&#xff0c;写成长字符 插入xml&#xff0c;注意两个点&#xff0c;否则会报错 1、长字符串字段不能写if判断&#xff1a;<if test"name ! null and name ! "> 2、插入的时候做字符串转码&#xff1a;<![CDATA[#{fileCode}]]> <insert …

验证FeignClient类型:FeignClient集成OkHttp

验证FeignClient类型 验证FeignClient类型 验证FeignClient类型 在SynchronousMethodHandler类中查看client类型

【自监督学习1】SimCLR论文阅读

文章目录 一、摘要二、引言三、方法3.1 主要框架3.2 训练一个大的batchsize 四、数据增强4.1 实验一 数据增强的组合对学习好的特征表达非常重要4.2 对比学习需要更多的数据增强 五、一些实验证明5.1 大模型更有利于无监督对比学习5.2 非线性层的预测头增加了特征表示5.3可调节…

字符设备实现内部驱动原理及分步注册流程

字符设备实现内部驱动原理&#xff1a; 应用层&#xff1a;open函数回调到驱动中open操作方法的路线&#xff1a; open&#xff08;&#xff09;--->sys_open()--->struct inode结构体--->struct cdev结构体--->struct file_operations结构体--->mycdev_open()…

RVEA多目标优化

A Reference Vector Guided Evolutionary Algorithm for Many-objective Optimization 目标函数预备知识参考向量引导选择更新参考向量流程整体框架参考向量引导选择参考向量自适应 for Many-objective Optimization) 目标函数 min ⁡ X f ( X ) ( f 1 ( X ) , f 2 ( X ) , . …

游泳耳机买什么牌子好一点?推荐四款出色的游泳耳机

游泳和跑步类似&#xff0c;短距离冲刺时&#xff0c;大脑没什么想法&#xff0c;而中长距离的有氧运动时&#xff0c;肉体是疲惫的&#xff0c;大脑是异常清晰的&#xff0c;时间却是格外难熬的。如何打发时间&#xff0c;让游泳锻炼变得不无聊&#xff0c;这是我从孩子时期就…