数据结构笔记--二叉树经典高频题

1--二叉树的最近公共祖先

主要思路:

        最近祖先只有两种情况:① 自底向上,当两个目的结点分别在当前结点的左右子树时,当前结点为两个目的结点的最近祖先;② 最近祖先与其中一个目的结点相同,则另一个目的结点在目的结点的子树上;

        递归寻找目的结点,当找到目的结点后往上返回目的结点,否则返回 NULL;当一个结点在左右子树上分别找到了两个目的结点,表明这个结点是最近祖先;否则返回不为空的子树的返回结点(这时两个结点对应第 ② 种情况);

#include <iostream>
#include <vector>
#include <stack>struct TreeNode {int val;TreeNode *left;TreeNode *right;TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};class Solution {
public:TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {if(root == NULL || root->val == p->val || root->val == q->val) return root;TreeNode* left = lowestCommonAncestor(root->left, p, q);TreeNode* right = lowestCommonAncestor(root->right, p, q);if(left != NULL && right != NULL) return root;else if( left != NULL) return left;else return right;}
};int main(int argc, char *argv[]){TreeNode *Node1 = new TreeNode(3);TreeNode *Node2 = new TreeNode(5);TreeNode *Node3 = new TreeNode(1);TreeNode *Node4 = new TreeNode(6);TreeNode *Node5 = new TreeNode(2);TreeNode *Node6 = new TreeNode(0);TreeNode *Node7 = new TreeNode(8);TreeNode *Node8 = new TreeNode(7);TreeNode *Node9 = new TreeNode(4);Node1->left = Node2;Node1->right = Node3;Node2->left = Node4;Node2->right = Node5;Node3->left = Node6;Node3->right = Node7;Node5->left = Node8;Node6->right = Node9;Solution S1;TreeNode* res = S1.lowestCommonAncestor(Node1, Node2, Node9);std::cout << res->val << std::endl;return 0;
}

2--二叉搜索树的中序后继结点

主要思路:

        如果 p 结点有右子树,则返回其右子树最左边的结点(中序遍历的定义);

        如果 p 结点没有右子树,则从 root 结点开始寻找 p 结点的父亲结点;(根据二叉搜索树的定义,可以节省寻找的时间,只需在一边进行寻找);

#include <iostream>
#include <vector>
#include <stack>struct TreeNode {int val;TreeNode *left;TreeNode *right;TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};class Solution {
public:TreeNode* inorderSuccessor(TreeNode* root, TreeNode* p) {TreeNode *res = NULL;if(p->right != NULL){ // p的中序后继是其右子树上最左的结点(即右字数上最先返回的结点)res = p->right;while(res->left != NULL) res = res->left;return res;}// p没有右子树,从root结点开始搜索p的父亲结点while(root != NULL){if(root->val > p->val){ // p在左子树上res = root;root = root->left; // 在左子树上找到最后一个比p大的结点(中序遍历是有序的,中序后继结点表明是比p结点大)}else{root = root->right; // p在右子树上}}return res;}
};int main(int argc, char *argv[]){TreeNode *Node1 = new TreeNode(2);TreeNode *Node2 = new TreeNode(1);TreeNode *Node3 = new TreeNode(3);Node1->left = Node2;Node1->right = Node3;Solution S1;TreeNode* res = S1.inorderSuccessor(Node1, Node2);std::cout << res->val << std::endl;return 0;
}

3--二叉树的序列化与反序列化

主要思路:

        利用前序遍历或层次遍历等方式进行序列化,再根据不同遍历的方式来设计反序列化的方式,利用反序列化重构二叉树;

        下面的代码使用了层次遍历进行序列化,并通过类似层次遍历的方式进行反序列化重构二叉树;

#include <iostream>
#include <string>
#include <vector>
#include <queue>struct TreeNode {int val;TreeNode *left;TreeNode *right;TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};class Codec {
public:std::string serialize(TreeNode* root) {std::string res = "";if (root == NULL) return res;std::queue<TreeNode*> q;q.push(root);res += std::to_string(root->val) + ",";while(!q.empty()){TreeNode* tmp = q.front();q.pop();if(tmp->left != NULL){q.push(tmp->left);res += std::to_string(tmp->left->val) + ",";}else res += "#,";if(tmp->right != NULL){q.push(tmp->right);res += std::to_string(tmp->right->val) + ",";}else res += "#,";}return res;}TreeNode* deserialize(std::string data) {if (data.length() == 0) return NULL;std::vector<std::string> value;for(auto i = 0; i < data.length(); i++){std::string tmp = "";while(data[i] != ','){tmp += data[i];i++;}value.push_back(tmp);}TreeNode *res = new TreeNode(std::stoi(value[0]));std::queue<TreeNode*> q;q.push(res);int idx = 1;while(!q.empty()){TreeNode* tmp = q.front();q.pop();if(value[idx] != "#"){ // 左儿子tmp->left = new TreeNode(std::stoi(value[idx]));q.push(tmp->left);} idx++;if(value[idx] != "#"){ // 右儿子tmp->right = new TreeNode(std::stoi(value[idx]));q.push(tmp->right);} idx++;}return res;}
};void printTreeNode(TreeNode *root){if (root == NULL) return;std::queue<TreeNode*> q;q.push(root);std::cout << root->val << " ";while(!q.empty()){TreeNode* tmp = q.front();q.pop();if(tmp->left != NULL){q.push(tmp->left);std::cout << tmp->left->val << " ";}else std::cout << "null" << " ";if(tmp->right != NULL){q.push(tmp->right);std::cout << tmp->right->val << " ";}else std::cout << "null" << " ";}
}int main(int argc, char *argv[]){//root = [1,2,3,null,null,4,5]TreeNode *Node1 = new TreeNode(1);TreeNode *Node2 = new TreeNode(2);TreeNode *Node3 = new TreeNode(3);TreeNode *Node4 = new TreeNode(4);TreeNode *Node5 = new TreeNode(5);Node1->left = Node2;Node1->right = Node3;Node3->left = Node4;Node3->right = Node5;Codec S1;std::cout << S1.serialize(Node1) << std::endl;TreeNode *res = S1.deserialize(S1.serialize(Node1));printTreeNode(res);return 0;
}

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

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

相关文章

Python-OpenCV中的图像处理-形态学转换

Python-OpenCV中的图像处理-形态学转换 形态学转换腐蚀膨胀开运算闭运算形态学梯度礼帽黑帽形态学操作之间的关系 形态学代码例程 形态学转换 形态学操作:腐蚀&#xff0c;膨胀&#xff0c;开运算&#xff0c;闭运算&#xff0c;形态学梯度&#xff0c;礼帽&#xff0c;黑帽等…

企业微信 企业内部开发 学习笔记

官方文档 文档 术语介绍 引入pom <dependency><groupId>com.github.binarywang</groupId><artifactId>wx-java-cp-spring-boot-starter</artifactId><version>4.5.3.B</version></dependency>核心代码 推送消息 final WxCp…

面试攻略,Java 基础面试 100 问(十一)

抽象类&#xff08;abstract class&#xff09;和接口&#xff08;interface&#xff09;有什么异同? 抽象类和接口都不能够实例化&#xff0c;但可以定义抽象类和接口类型的引用。一个类如果继承了某个抽象类或者实现了某个接口都需要对其中的抽象方法全部进行实现&#xff…

英码国产高配边缘计算盒子上市!搭载TPU处理器BM1684X,适配麒麟系统,支持OTA升级!

随着人工智能技术不断深入实际应用场景&#xff0c;加速各行各业场景应用落地&#xff0c;边缘计算的重要性越发凸显。相较于传统的集中式云计算&#xff0c;边缘计算在距离数据源或用户更近的地方提供计算能力&#xff0c;不仅满足了对实时性要求较高的场景应用需求&#xff0…

如何通过CSS选择器选择一个元素的子元素?如何选择第一个子元素和最后一个子元素?

聚沙成塔每天进步一点点 ⭐ 专栏简介⭐ 选择一个元素的子元素⭐ 选择第一个子元素和最后一个子元素⭐ 注意事项⭐ 写在最后 ⭐ 专栏简介 前端入门之旅&#xff1a;探索Web开发的奇妙世界 记得点击上方或者右侧链接订阅本专栏哦 几何带你启航前端之旅 欢迎来到前端入门之旅&…

线程池,以及线程池的实现以及面试常问的问题,工厂模式,常见的锁策略(面试常考,要了解,不行就背)

一、&#x1f49b; 线程池的基本介绍 内存池&#xff0c;进程池&#xff0c;连接池&#xff0c;常量池&#xff0c;这些池子概念上都是一样的&#xff5e;&#xff5e; 如果我们需要频繁的创建销毁线程&#xff0c;此时创建销毁的成本就不能忽视了&#xff0c;因此就可以使用线…

Redis系列(一):深入了解Redis数据类型和底层数据结构

Redis有以下几种常用的数据类型&#xff1a; redis数据是如何组织的 为了实现从键到值的快速访问&#xff0c;Redis 使用了一个哈希表来保存所有键值对。 Redis全局哈希表&#xff08;Global Hash Table&#xff09;是指在Redis数据库内部用于存储所有键值对的主要数据结构。…

安卓13不再支持PPTP怎么办?新的连接解决方案分享

随着Android 13的发布&#xff0c;我们迎来了一个令人兴奋的新品时刻。然而&#xff0c;对于一些用户而言&#xff0c;这也意味着必须面对一个重要的问题&#xff1a;Android 13不再支持PPTP协议。如果你是一个习惯使用PPTP协议来连接换地址的用户&#xff0c;那么你可能需要重…

C++ 泛型编程:函数模板

文章目录 前言一、什么是泛型编程二、函数模板三、函数模板的使用四、多参数函数模板五&#xff0c;示例代码&#xff1a;总结 前言 当需要编写通用的代码以处理不同类型的数据时&#xff0c;C 中的函数模板是一个很有用的工具。函数模板允许我们编写一个通用的函数定义&#…

接口测试之Jmeter+Ant+Jenkins接口自动化测试平台

平台简介 一个完整的接口自动化测试平台需要支持接口的自动执行&#xff0c;自动生成测试报告&#xff0c;以及持续集成。Jmeter支持接口的测试&#xff0c;Ant支持自动构建&#xff0c;而Jenkins支持持续集成&#xff0c;所以三者组合在一起可以构成一个功能完善的接口自动化…

idea - 刷新 Git 分支数据 / 命令刷新 Git 分支数据

一、idea - 刷新 Git 分支数据 idea 找到 fetch 选项&#xff0c;重新获取分支数据 二、命令刷新 Git 分支数据 git fetch参考链接 1. 远程Gitlab新建的分支在IDEA里不显示

jxls导出问题

![请添加图片描述](https://img-blog.csdnimg.cn/bc74c4207818491c93b75e19b3333451.png 为什么最后导出的文件还是按原样导出啊&#xff0c;没有填充数据 ![在这里插入图片描述](https://img-blog.csdnimg.cn/d4500b9a98c042f6b64a5d0650071303.png

ChatGPT等人工智能编写文章的内容今后将成为常态

BuzzFeed股价上涨200%可能标志着“转向人工智能”媒体趋势的开始。 周四&#xff0c;一份内部备忘录被华尔街日报透露BuzzFeed正计划使用ChatGPT聊天机器人-风格文本合成技术来自OpenAI&#xff0c;用于创建个性化盘问和将来可能的其他内容。消息传出后&#xff0c;BuzzFeed的…

文本三剑客之grep命令和awk命令 1.0 版本

grep awk 1.grep命令1.1 基本格式1.2 常用选项 2.awk命令2.1 awk工作原理2.2 awk命令格式2.3 awk常用内置变量 1.grep命令 1.1 基本格式 grep [选项]… 查找条件 目标文件1.2 常用选项 选项功能 -m [ x ]匹配x次 后停止,x为具体数字-v取反 -i忽略字符大小写 -n显示匹配的 …

Dynamic CRM开发 - 实体介绍

实体简介 在CRM中,实体(Entity)是数据的基本载体,也是构建业务逻辑网络的基础节点。 实体可以理解为数据库中的一张表(实体中的字段对应数据库表的字段),比如创建一个实体存储客户信息,创建一个实体存储产品信息,产品实体里可以创建一个查找类型的字段(类似表的外键)…

【三维编辑】Seal-3D:基于NeRF的交互式像素级编辑

文章目录 摘要一、引言二、方法2.1.基于nerf的编辑问题概述2.2.编辑指导生成2.3.即时预览的两阶段学生训练 三、实验四、代码总结 项目主页: https://windingwind.github.io/seal-3d/ 代码&#xff1a;https://github.com/windingwind/seal-3d/ 论文: https://arxiv.org/pdf/23…

阿里云轻量应用服务器_2核4G4M_2核2G3M_性能测评

阿里云轻量应用服务器2核2G3M带宽108元一年&#xff0c;系统盘为50GB高效云盘&#xff1b;轻量服务器2核4G4M带宽&#xff0c;60GB高效云盘297.98元12个月。目前轻量应用服务器只有2核2G和2核4G有活动&#xff0c;阿里云百科分享阿里云轻量应用服务器入口&#xff1a; 目录 阿…

【Qt高阶】老Qt都不一定清楚的“QObject线程亲和性”【2023.08.13】

老Qt都不一定清楚的“线程亲和性” 与题目无关 感觉自己还挺2&#xff0c;有粉丝点了那个契约者会给up发个鼓励的话&#xff0c;我还以为是人私信发的&#xff0c;都挨个感谢了&#xff0c;后来才意识到是系统自动发的&#x1f623;&#x1f623;&#x1f623;。 自上上期视频对…

Three.js阴影

目录 Three.js入门 Three.js光源 Three.js阴影 Three.js纹理贴图 使用灯光后&#xff0c;场景中就会产生阴影。物体的背面确实在黑暗中&#xff0c;这称为核心阴影&#xff08;core shadow&#xff09;。我们缺少的是落下的阴影&#xff08;drop shadow&#xff09;&#…

【数据结构】——栈、队列的相关习题

目录 题型一&#xff08;栈与队列的基本概念&#xff09;题型二&#xff08;栈与队列的综合&#xff09;题型三&#xff08;循环队列的判空与判满&#xff09;题型四&#xff08;循环链表表示队列&#xff09;题型五&#xff08;循环队列的存储&#xff09;题型六&#xff08;循…