二叉搜索树经典笔试题【力扣、牛客】
文章目录
- 1.根据二叉树创建字符串
- 2. 二叉树的层序遍历
- 3.二叉树的层序遍历Ⅱ
- 4.二叉树的最近公共祖先
- 1.法一:定位p、q在左还是右 分类讨论
- 2.法二:利用stack求出p、q路径 求相交值
- 5.二叉搜索树与双向链表
- 1.法一:递归:递归过程修正指针指向
- 2.数组:将二叉搜索树进行中序遍历可以得到由小到大的顺序排列
- 6.前序中序遍历序列构造二叉树
- 7.中序后序遍历序列构造二叉树
- 8.二叉树的前序遍历【非递归】
- 9.二叉树的中序遍历【非递归】
- 10.二叉树的后序遍历【非递归】
- 1.法一:栈模拟实现递归
- 2.法二:前序遍历修改
1.根据二叉树创建字符串
根据二叉树创建字符串


struct TreeNode
{int val;TreeNode* left;TreeNode* right;TreeNode(): val(0), left(nullptr), right(nullptr){}TreeNode(int x): val(x), left(nullptr), right(nullptr){}TreeNode(int x, TreeNode* eft, TreeNode* right): val(x), left(left), right(right){}
};//图一分析:
//左不空 (左递归直至遇空返回上一层)
//然后在当层判断右子树
//右空 (返回上层 + )
//右不空 (左递归直至遇空返回上一层)
//然后在当层判断右子树
//右空 (返回上一层 + )//图二分析:
//左不空 (左递归直至遇空返回上一层)
//然后在当层判断右子树
//右不空 (左递归直至遇空返回上一层)
//然后在当层判断右子树
//右空 (返回上层 + )
//右不空 (左递归直至遇空返回上一层)//左不空 右空 --省略
// 左空时第一个if两个条件才判断完
//左空 右空 --省略
//左空 右不空 --不省略
class Solution
{
public:string tree2str(TreeNode* root){if (root == nullptr)return "";string str = to_string(root->val);//遍历完根后遍历左 遍历左的前提是左不空 如果左空看看右空不空//如果右也空没必要遍历 return//如果右不空 正常遍历if (root->left || root->right){str += '(';str += tree2str(root->left);str += ')';}if (root->right) //遍历完左后遍历右 遍历右的前提是右不空 //右不空 正常遍历 右空 【看注释知右空的一律省略 直接return】{str += '(';str += tree2str(root->right);str += ')';}return str;}
};
2. 二叉树的层序遍历
二叉树的层序遍历


点击 二叉树【C】 查看上篇博客中的层序遍历

struct TreeNode
{int val;TreeNode* left;TreeNode* right;TreeNode(): val(0), left(nullptr), right(nullptr){}TreeNode(int x): val(x), left(nullptr), right(nullptr){}TreeNode(int x, TreeNode* eft, TreeNode* right): val(x), left(left), right(right){}
};class Solution
{
public:vector<vector<int>> levelorder(TreeNode* root) {queue<TreeNode*> q;int LevelNodeCount = 0;if (root){q.push(root);LevelNodeCount = 1;}vector<vector<int>> vv;while (!q.empty()){vector<int> v;while (LevelNodeCount--){TreeNode* front = q.front();q.pop();v.push_back(front->val);if (front->left)q.push(front->left);if (front->right)q.push(front->right);}vv.push_back(v);LevelNodeCount = q.size();}return vv;}
};
3.二叉树的层序遍历Ⅱ
二叉树的层序遍历Ⅱ



class Solution
{
public:vector<vector<int>> levelorder(TreeNode* root) {queue<TreeNode*> q;int LevelNodeCount = 0;if (root){q.push(root);LevelNodeCount = 1;}vector<vector<int>> vv;while (!q.empty()){vector<int> v;while (LevelNodeCount--){TreeNode* front = q.front();q.pop();v.push_back(front->val);if (front->left)q.push(front->left);if (front->right)q.push(front->right);}vv.push_back(v);LevelNodeCount = q.size();}reverse(vv.begin(), vv.end());return vv;}
};
4.二叉树的最近公共祖先
二叉树的最近公共祖先


1.法一:定位p、q在左还是右 分类讨论
T(N)=O(N^2)
最坏情况:树为单链即均在左侧或右侧,p、q均在单侧的底部
判断p、q的左右侧时 n-2 n-1
假设p、q均在左侧 接下来递归到左子树 继续判断p、q中是否为根?在左?在右?n-3 n-2 …
class Solution
{
public:bool IsInTree(TreeNode* root, TreeNode* x){if (root == nullptr)return false;return root == x|| IsInTree(root->left, x)|| IsInTree(root->right,x);}//求p、q的最近公共祖先TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q){if (root == nullptr)return nullptr;//p、q其中一个是根 那么根就为objif (root == p || root == q)return root;//判断p、q在左 ?右bool pInLeft = IsInTree(root->left, p);bool pInRight = !pInLeft;bool qInLeft = IsInTree(root->left, q);bool qInRight = !qInLeft;//一左一右==》root为objif ((pInLeft && qInRight) || (pInRight && qInLeft))return root;//均左==》递归到左子树if (pInLeft && qInLeft)return lowestCommonAncestor(root->left, p, q);//均右==》递归到右子树elsereturn lowestCommonAncestor(root->right, p, q);}
};
2.法二:利用stack求出p、q路径 求相交值
class Solution
{
public:bool GetPath(TreeNode* root, TreeNode* pobj, stack<TreeNode*>& route){if (root == nullptr)return false;route.push(root);if (root == pobj)return true;if (GetPath(root->left, pobj, route))return true;if (GetPath(root->right, pobj, route))return true;route.pop();return false;}TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {stack<TreeNode*> pRoute;stack<TreeNode*> qRoute;GetPath(root, p, pRoute);GetPath(root, q, qRoute);//找路径相遇点while (pRoute.size() != qRoute.size()){if (pRoute.size() > qRoute.size())pRoute.pop();elseqRoute.pop();}while (pRoute.top() != qRoute.top()){pRoute.pop();qRoute.pop();}return pRoute.top();}
};
5.二叉搜索树与双向链表
二叉搜索树与双向链表


1.法一:递归:递归过程修正指针指向
class Solution
{
public: //中序遍历void InOrderConvert(TreeNode* cp, TreeNode*& prv){if (cp == nullptr)return;InOrderConvert(cp->left, prv);//一路向左 遇空返回上一层//前左指向前驱cp->left = prv;//left==prv即left指向prv所指向的结点//前驱非空 前结点的right指向后面那个结点if (prv)prv->right = cp;//更新prvprv = cp;//一路向右 遇空返回上一层InOrderConvert(cp->right, prv);}//==》当前层函数结束 返回上一层TreeNode* Convert(TreeNode* pRootOfTree){TreeNode* prev = nullptr;InOrderConvert(pRootOfTree, prev);TreeNode* head = pRootOfTree;//当传一颗空树 head在此就发挥了作用while (head && head->left)head = head->left;return head;}
};
2.数组:将二叉搜索树进行中序遍历可以得到由小到大的顺序排列
/*
struct TreeNode
{int val;struct TreeNode *left;struct TreeNode *right;TreeNode(int x) :val(x), left(NULL), right(NULL) {}
};
*/class Solution
{
public:vector<TreeNode*> v;void inorder(TreeNode* root) {if (!root) return;inorder(root->left);v.push_back(root);inorder(root->right);}TreeNode* Convert(TreeNode* pRootOfTree) {if (!pRootOfTree) return pRootOfTree;inorder(pRootOfTree);for (int i = 0; i < v.size() - 1; i++) { v[i]->right = v[i + 1];v[i + 1]->left = v[i];}return v[0];}};
6.前序中序遍历序列构造二叉树
前序中序遍历序列构造二叉树

class Solution
{
public:TreeNode* _buildTree(vector<int>& preorder, vector<int>& inorder, int& i, int begin, int end){if (begin > end) return nullptr;//遍历inorder 定位到根节点//[begin, x - 1] x [x + 1, end]int x = begin;for (x = begin; x <= end; ++x){if (inorder[x] == preorder[i])break;}TreeNode* root = new TreeNode(preorder[i++]);root->left = _buildTree(preorder, inorder, i, begin, x - 1);root->right = _buildTree(preorder, inorder, i, x + 1, end);return root;};TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder){int index = 0;//前序遍历数组第一个元素即根节点return _buildTree(preorder, inorder, index, 0, inorder.size() - 1);}
};
7.中序后序遍历序列构造二叉树
中序后序遍历序列构造二叉树

class Solution
{
public:TreeNode* _buidTree(vector<int>& inorder, vector<int>& postorder, int& i, int begin, int end){if (begin > end) return nullptr;int x = begin;for (x = begin; x <= end; ++x){if (inorder[x] == postorder[i])break;}TreeNode* root = new TreeNode(postorder[i--]);root->right = _buidTree(inorder, postorder, i, x + 1, end);root->left = _buidTree(inorder, postorder, i, begin, x - 1);return root;}TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) {int index = postorder.size() - 1;return _buidTree(inorder, postorder, index, 0, inorder.size() - 1);}
};
8.二叉树的前序遍历【非递归】
二叉树的前序遍历


vector<int> preorderTraversal(TreeNode* root)
{vector<int> v; //v存储遍历的数据stack<TreeNode*> st; //利用栈的特点 调整读取数据的顺序存入到v中TreeNode* cp = root;while (cp || !st.empty()){//左路结点while (cp){v.push_back(cp->val);st.push(cp);cp = cp->left;}//左路结点的右子树TreeNode* top = st.top();cp = top->right;st.pop();}return v;
}
9.二叉树的中序遍历【非递归】
二叉树的中序遍历

vector<int> inorderTraversal(TreeNode* root)
{vector<int> v;stack<TreeNode*> st;TreeNode* cp = root;while (cp || !st.empty()) {while (cp){st.push(cp);cp = cp->left;}TreeNode* top = st.top();v.push_back(top->val);cp = top->right;st.pop();}return v;
};
10.二叉树的后序遍历【非递归】
二叉树的后序遍历

1.法一:栈模拟实现递归
vector<int> postorderTraversal(TreeNode* root)
{vector<int> v;stack<TreeNode*> st;TreeNode* cp = root;TreeNode* prv = nullptr;while (cp || !st.empty()){while (cp){st.push(cp);cp = cp->left;}TreeNode* top = st.top();if (top->right == nullptr || top->right == prv){v.push_back(top->val);prv = top;st.pop();}else{cp = top->right;}}return v;
};
2.法二:前序遍历修改
class Solution
{
public:vector<int> postorderTraversal(TreeNode* root) {vector<int> v;stack<TreeNode*> st;st.push(root);while (!st.empty()){TreeNode* top = st.top();st.pop();if (top)v.push_back(top->val);elsecontinue;st.push(top->left);st.push(top->right);}reverse(v.begin(), v.end());return v;}
};
相关文章:
二叉搜索树经典笔试题【力扣、牛客】
文章目录 1.根据二叉树创建字符串2. 二叉树的层序遍历3.二叉树的层序遍历Ⅱ4.二叉树的最近公共祖先1.法一:定位p、q在左还是右 分类讨论2.法二:利用stack求出p、q路径 求相交值 5.二叉搜索树与双向链表1.法一:递归:递归过程修正指…...
docker系列(1) - docker环境篇
文章目录 1. docker环境1.1 docker安装1.2 阿里云镜像加速器1.2 docker管理工具(portainer)1.3 docker网络1.3.1 网络说明1.3.2 创建指定网关的网络 1. docker环境 1.1 docker安装 #CentOS 6 rpm -iUvh http://dl.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noar…...
web安全漏洞-SQL注入攻击实验
实验目的 学习sql显注的漏洞判断原理掌握sqlmap工具的使用分析SQL注入漏洞的成因 实验工具 sqlmap是用python写的开源的测试框架,支持MySQL,Oracle,PostgreSQL,Microsoft SQL Server,Microsoft Access,I…...
直接插入排序(C++实现)
文章目录 1. 基础概念🍑 内部排序和外部排序 2. 直接插入排序3. 动图演示4. 代码实现5. 性能分析 无论是日常生活还是很多科学领域当中,排序都是会经常面对的问题,比如按成绩对学校的学生排序,按薪水多少对公司员工排序等。 根据…...
【k8s】Pod 的钩子
Kubernetes(K8s)中的 Pod 可以使用以下几种勾子(钩子)来执行在容器生命周期的不同阶段运行的操作: PostStart(启动后):该勾子在容器启动之后立即运行。它可以用于在容器内执行一些初…...
MCU软核 3. Xilinx Artix7上运行cortex-m3软核
0. 环境 - win10 vivado 2018.3 keil mdk - jlink - XC7A35TV12 1. 下载资料 https://keilpack.azureedge.net/pack/Keil.V2M-MPS2_DSx_BSP.1.1.0.pack https://gitee.com/whik/cortex_m3_on_xc7a100t 2. vivado 2018 Create Project -> Next -> -> Project n…...
基于SpringbootShiro实现的CAS单点登录
概述 单点登录(Single Sign On,SSO)是一种登录管理机制,主要用于多系统集成,即在多个系统中,用户只需要到一个中央服务器登录一次即可访问这些系统中的任何一个,无须多次登录。常见的例子就是,…...
SocketTool V4.0 使用说明
TCP/UDP Socket 调 试 工 具 提 供 了 TCP Server,TCP Client,UDP Server,UDP Client,UDP Group 五种 Socket 调试方案。 下面是一份简要的使用流程: TCP 通信测试: 1) 创建 TCP Server 选中左方的 TCP Server, 然后点击 ”创建 ”按钮,软件弹…...
Jenkins结合allure生成测试报告
前言: 我们在做自动化测试的过程中最重要的肯定是报告的输出啦,最近几年allure可以说是最最主流报告展示工具啦。 一、服务端安装allure 在安装Jenkins的机器 安装allure,我们在Jenkins上能跑动前提是在对应服务器上代码能正常运行…...
【Linux】缓冲区/回车换行
1、缓冲区 C程序默认有输出缓冲区。数据输出时,被及时看到,是立马刷新了;如果没被看到,是被暂存在数据缓冲区中。fflush(stdout); 【强制刷新】\n【行刷新,也是一种刷新方式】 2、回车换行 \n【回车换行】输入完一行内…...
Java手写插入排序和算法案例拓展
1. Java手写插入排序和算法案例拓展 1.1 算法思维导图 #mermaid-svg-jIZ3LAdg1NLcOvaM {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-jIZ3LAdg1NLcOvaM .error-icon{fill:#552222;}#mermaid-svg-jIZ3LAdg1NLcOvaM…...
Python Opencv实践 - 视频文件操作
参考资料: 视频处理VideoCapture类---OpenCV-Python开发指南(38)_python opencv videocapture_李元静的博客-CSDN博客 OpenCV VideoCapture.get()参数详解 - 简书FOURCC四字符码对照表_4fvcc_Kellybook的博客-CSDN博客 import cv2 as cv im…...
HCS 中的一些概念(二)
一、Service OM 1、首页(资源状态) 2、服务列表 计算资源:计算资源又分为可用分区(AZ)、规格和虚拟机组,可在此处创建虚拟机、虚拟机组、主机组和规格 网络资源:网络资源又分为物理网络…...
Scanner类用法(学习笔记)
Scanner类用法(学习笔记,后续会补充) 1.next()用法 package com.yushifu.scanner; import java.util.Scanner;//util java工具包 //Scanner类(获取用户的输入) Scanner s new Scanner&#…...
idea2021.1.3版本双击启动,没反应
今天打开电脑,点开idea,界面悬在这里,几秒然后就是没了。然后就一直打不开idea了。 然后又是卸载重装,又是删除缓存文件。我把电脑关于idea的文件全都删除了 。重新安装后(首次运行倒是可以打开,但是关掉id…...
MC-4/11/01/400 ELAU 软件允许用户完全访问相机设置
MC-4/11/01/400 ELAU 软件允许用户完全访问相机设置 一个完整的Sentinel模具保护解决方案包括一到四台冲击式摄像机、专用红外LED照明和镜头、Sentinel软件以及所有与模压机连接的必要互连组件。摄像机支架基于磁性,可快速、安全、灵活地部署。此外,一个…...
Error contacting service. It is probably not running.问题解决
一 问题描述 Error contacting service. It is probably not running. 查看zookeeper 目录下数据目录下的zookeeper.out 如果你没找到这个目录那么 OK 你的问题就是 zoo.cfg 文件中数据目录设置错误 zookeeper.out下报错 ERROR [main:QuorumPeerMain86] - Invalid config,…...
01_网络编程_传统IO
网络编程 1.什么是网络编程 在网络通信协议下,不同计算机上运行的程序,进行的数据传输。 如果想把一个计算的结果,或者是电脑上的文件通过网络传递给你的朋友,就需要用到网络编程。 在实际生活中,网络通信无处不在…...
vue 检查指定路由是否存在
今天路由跳转报错了 RangeError: Maximum call stack size exceeded 但显然 我的代码只有一个简单的路由跳转 并没有很大的的堆栈数据操作 所以 我就联想到了 会不会是因为路由不存在 我们可以通过 console.log(this.$router.options.routes)输出整个路由对象类看一下 或者…...
自动化办公更简单了:新版python-office,有哪些更新?
#职场经验谈# 大家好,这里是程序员晚枫,小破站/小红薯都叫这个名。 去年4月开源了一个Python自动化办公项目:python-office,GitHub和Gitee都能看到。1行代码实现复杂的自动化办公任务,帮助不懂代码的小白,…...
DeepSeek 赋能智慧能源:微电网优化调度的智能革新路径
目录 一、智慧能源微电网优化调度概述1.1 智慧能源微电网概念1.2 优化调度的重要性1.3 目前面临的挑战 二、DeepSeek 技术探秘2.1 DeepSeek 技术原理2.2 DeepSeek 独特优势2.3 DeepSeek 在 AI 领域地位 三、DeepSeek 在微电网优化调度中的应用剖析3.1 数据处理与分析3.2 预测与…...
.Net框架,除了EF还有很多很多......
文章目录 1. 引言2. Dapper2.1 概述与设计原理2.2 核心功能与代码示例基本查询多映射查询存储过程调用 2.3 性能优化原理2.4 适用场景 3. NHibernate3.1 概述与架构设计3.2 映射配置示例Fluent映射XML映射 3.3 查询示例HQL查询Criteria APILINQ提供程序 3.4 高级特性3.5 适用场…...
IGP(Interior Gateway Protocol,内部网关协议)
IGP(Interior Gateway Protocol,内部网关协议) 是一种用于在一个自治系统(AS)内部传递路由信息的路由协议,主要用于在一个组织或机构的内部网络中决定数据包的最佳路径。与用于自治系统之间通信的 EGP&…...
在 Nginx Stream 层“改写”MQTT ngx_stream_mqtt_filter_module
1、为什么要修改 CONNECT 报文? 多租户隔离:自动为接入设备追加租户前缀,后端按 ClientID 拆分队列。零代码鉴权:将入站用户名替换为 OAuth Access-Token,后端 Broker 统一校验。灰度发布:根据 IP/地理位写…...
【git】把本地更改提交远程新分支feature_g
创建并切换新分支 git checkout -b feature_g 添加并提交更改 git add . git commit -m “实现图片上传功能” 推送到远程 git push -u origin feature_g...
DBAPI如何优雅的获取单条数据
API如何优雅的获取单条数据 案例一 对于查询类API,查询的是单条数据,比如根据主键ID查询用户信息,sql如下: select id, name, age from user where id #{id}API默认返回的数据格式是多条的,如下: {&qu…...
GitHub 趋势日报 (2025年06月08日)
📊 由 TrendForge 系统生成 | 🌐 https://trendforge.devlive.org/ 🌐 本日报中的项目描述已自动翻译为中文 📈 今日获星趋势图 今日获星趋势图 884 cognee 566 dify 414 HumanSystemOptimization 414 omni-tools 321 note-gen …...
vue3+vite项目中使用.env文件环境变量方法
vue3vite项目中使用.env文件环境变量方法 .env文件作用命名规则常用的配置项示例使用方法注意事项在vite.config.js文件中读取环境变量方法 .env文件作用 .env 文件用于定义环境变量,这些变量可以在项目中通过 import.meta.env 进行访问。Vite 会自动加载这些环境变…...
Web 架构之 CDN 加速原理与落地实践
文章目录 一、思维导图二、正文内容(一)CDN 基础概念1. 定义2. 组成部分 (二)CDN 加速原理1. 请求路由2. 内容缓存3. 内容更新 (三)CDN 落地实践1. 选择 CDN 服务商2. 配置 CDN3. 集成到 Web 架构 …...
安宝特案例丨Vuzix AR智能眼镜集成专业软件,助力卢森堡医院药房转型,赢得辉瑞创新奖
在Vuzix M400 AR智能眼镜的助力下,卢森堡罗伯特舒曼医院(the Robert Schuman Hospitals, HRS)凭借在无菌制剂生产流程中引入增强现实技术(AR)创新项目,荣获了2024年6月7日由卢森堡医院药剂师协会࿰…...
