C++ 二叉树OJ题

💓博主CSDN主页:麻辣韭菜-CSDN博客💓

⏩专栏分类:C++知识分享⏪

🚚代码仓库:C++高阶🚚

🌹关注我🫵带你学习更多C++知识
  🔝🔝

前言

C++二叉搜索树 这篇讲解了搜索二叉树的实现的,本篇从实战出发,让大家更好的掌握和理解二叉树的!!!!



1. 二叉树创建字符串。606. 根据二叉树创建字符串 - 力扣(LeetCode)

 

找出规律,我们就好办了 直接代码演示。 

class Solution {
public:string tree2str(TreeNode* root) {if(root == nullptr) //根为空 直接返回空串!return "";string str  = to_string(root->val); //外面解释这个函数//结合 刚才的3点总结 左右都为空不加括号,左为空是要加括号的。 if(root->left || root->right){str += '(';str += tree2str(root->left);str += ')';}if(root->right){str += '(';str += tree2str(root->right);str += ')';}return str;}
};

 to_string 是 C++ 标准库中的一个函数,它定义在 <string> 头文件中。这个函数用于将一个数值类型(如 intdouble 等)转换为其对应的字符串表示形式。 在给出的代码片段中,to_string(root->val) 被用来将 TreeNode 对象的 val 属性(假设是一个数值类型)转换为一个字符串。这样,就可以将该字符串与其他部分拼接起来,形成最终的树形结构字符串表示。 例如,如果 root->val 是整数 3,那么 to_string(root->val) 将返回字符串 "3"。 简而言之,to_string 函数在 C++ 中用于数值到字符串的转换。在你的代码中,它被用来将树节点的值转换为字符串,以便构建树结构的字符串表示。

这里有点难理解是左不为空,右为空。按照上面条件不是就错了吗?

我们按照题的要求前序遍历,是先根在左然后右 看递归展开图  

 

递归是一层一层展开,如果左不为空,右为空它们就会像上图那样一直找到左为空为止,

这时在递归右子树 。

 


2. 二叉树的分层遍历1。102. 二叉树的层序遍历 - 力扣(LeetCode)

解题思路 :我们创建一个队列,前序遍历这个数组,每遍历一次,就进队列一次,

根据队列的性质先进先出。就解决了!!! 

class Solution {
public:vector<vector<int>> levelOrder(TreeNode* root) {queue<TreeNode* > q; //创建队列int levelSize = 0; //层数变量vector<vector<int>> vv;if(root) //节点不为空进队列{q.push(root);levelSize = 1; //为什么是1 根就只有一个。}while(!q.empty()) //如果队列不为空{vector<int> v;while(levelSize){TreeNode* front = q.front();q.pop();//出队列v.push_back(front->val); //把队顶的数据压进顺序表V//带入下一层if(front->left)q.push(front->left);if(front->right)q.push(front->right);--levelSize;}vv.push_back(v); //把每一层出完,压进二维的顺序表levelSize = q.size();//更新每一层,数据有多少个。}return vv;}
};

 


3. 二叉树的分层遍历2。107. 二叉树的层序遍历 II - 力扣(LeetCode)

这个题没什么好说的,来个投机的,把第二题逆置再返回。 

 

class Solution {
public:vector<vector<int>> levelOrderBottom(TreeNode* root) {queue<TreeNode* > q; //创建队列int levelSize = 0; //层数变量vector<vector<int>> vv;if(root) //节点不为空进队列{q.push(root);levelSize = 1; //为什么是1 根就只有一个。}while(!q.empty()) //如果队列不为空{vector<int> v;while(levelSize){TreeNode* front = q.front();q.pop();//出队列v.push_back(front->val); //把队顶的数据压进顺序表V//带入下一层if(front->left)q.push(front->left);if(front->right)q.push(front->right);--levelSize;}vv.push_back(v); //把每一层出完,压进二维的顺序表levelSize = q.size();//更新每一层,数据有多少个。}reverse(vv.begin(),vv.end()); //用迭代器逆置return vv;}};

 

4. 给定一个二叉树, 找到该树中两个指定节点的最近公共祖先 。

236. 二叉树的最近公共祖先 - 力扣(LeetCode)

 

解题思路 根据解释,我们可以得出 一个在我的左子树,一个在我的右子树。我就是公共祖先。那我们可以用路径相交思路来解决,比如7和0的公共祖先。根据递归深度路径大小,

让深度更深的那个先走,等它们深度一样时,同时再走,最后相等的那个值就是公共祖先。

class Solution {
public:bool GetPath(TreeNode* root,TreeNode* x,stack<TreeNode*>& path){if(root == nullptr) //根都为空了 还找个屁{return false;}//不为空进栈path.push(root);if(root == x) // 找到了{return true;}if(GetPath(root->left,x,path)) //左递归{return true;}if(GetPath(root->right,x,path))//右递归{return true;}path.pop();//刚才条件说 一个在我的右,一个在我的左,这里左右都为空了肯定不是祖先,出栈。return false;}TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {stack<TreeNode*> pPath,qPath; //这里用栈 先进后出GetPath(root,p,pPath);GetPath(root,q,qPath);while(qPath.size() != pPath.size()){if(qPath.size()>pPath.size())qPath.pop();elsepPath.pop();}while(qPath.top() != pPath.top()){qPath.pop();pPath.pop();}return qPath.top();}
};

 


 

5. 二叉树搜索树转换成排序双向链表。二叉搜索树与双向链表_牛客题霸_牛客网 (nowcoder.com)

解题思路:中序遍历,然后 改链接方向,如何改?根的左就是prev。 右怎么改?记录父亲节点,根的右就是父亲节点  以4举例:4的左为空,那它连接就是nullptr,再看右为空返回上一层这时父亲连接它的右 

class Solution {
public:void InorderConvert(TreeNode* cur, TreeNode*& prev){if(cur == nullptr)return ;InorderConvert(cur->left,prev);cur->left = prev;if(prev)prev->right = cur;prev = cur;InorderConvert(cur->right,prev);}TreeNode* Convert(TreeNode* pRootOfTree){TreeNode* prev = nullptr;InorderConvert(pRootOfTree,prev);TreeNode* head = pRootOfTree;while (head && head->left) {head = head->left;}return head;}};

 

 


6. 根据一棵树的前序遍历与中序遍历构造二叉树。 105. 从前序与中序遍历序列构造二叉树 - 力扣(LeetCode)

 解题思路:前序确定什么? 确定根, 中序确定什么? 确定根的左右区间 

class Solution {
public:TreeNode* _buildTree(vector<int>& preorder, vector<int>& inorder, int& prei, int inbegin, int inend){if(inbegin > inend){return nullptr;}TreeNode* root = new TreeNode(preorder[prei]);int rooti = inbegin;//分割区间while(rooti< inend){if(inorder[rooti] == preorder[prei]){break;}elserooti++;}++prei;// 区间[inbegin, rooti-1] prei [rooti+1,inend] //转化成子问题root->left = _buildTree(preorder,inorder,prei,inbegin,rooti-1);root->right = _buildTree(preorder,inorder,prei,rooti+1,inend);return root;}TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {int i = 0;return _buildTree(preorder, inorder, i, 0, inorder.size()-1);}
};

 


7. 根据一棵树的中序遍历与后序遍历构造二叉树。106. 从中序与后序遍历序列构造二叉树 - 力扣(LeetCode)

  解题思路:还是一样,中序确定根的左右区间,后序确定根。先创建右再创建左

 

​
class Solution {
public:TreeNode*  _buildTree(vector<int>& inorder, vector<int>& postorder,int& posti,int inbegin, int inend){if(inbegin > inend){return nullptr;}TreeNode* root = new TreeNode(postorder[posti]);int rooti = inbegin;while(rooti < inend){if(inorder[rooti] == postorder[posti])break;else++rooti;}++posti;root->right= _buildTree(inorder, postorder,posti ,rooti+1, inend);root->left= _buildTree(inorder, postorder,posti ,inbegin, rooti-1);return root;}TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) {int i = 0;reverse(postorder.begin(),postorder.end());return _buildTree(inorder, postorder,  i, 0, inorder.size()-1); }
};​

 


8. 二叉树的前序遍历,非递归迭代实现 144. 二叉树的前序遍历 - 力扣(LeetCode)

class Solution {
public:vector<int> preorderTraversal(TreeNode* root) {//迭代用栈 stack<TreeNode*> s;vector<int> v;TreeNode* cur = root;while(cur || !s.empty()){//开始访问while(cur)v.push_back(cur->val);s.push(cur)cur = cur->left;}//访问右树TreeNode* top = s.top();s.pop();cur = top->right;}return v;
};

 

 


9. 二叉树中序遍历 ,非递归迭代实现。94. 二叉树的中序遍历 - 力扣(LeetCode)

解题思路:和前序不同的是 先访问左 再访问根 然后右。那这样的话 一直迭代到左树为空为止,然后取栈中取元素 push到vector中,最后访问右树。

 

class Solution {
public:vector<int> inorderTraversal(TreeNode* root) {vector<int> v;stack<TreeNode*> s;TreeNode* cur = root;while(cur || !s.empty()){while(cur){s.push(cur);cur = cur->left;}TreeNode* top = s.top();s.pop();v.push_back(top->val);cur = top->right;}return v;}
};

 


10. 二叉树的后序遍历 ,非递归迭代实现。145. 二叉树的后序遍历 - 力扣(LeetCode)

 

解题思路:后序 先左再右然后根  右为空了再取栈顶的元素,这里不一样的是 如果左右都不空 怎么访问根? 看下图

 

从这个图可以说明 上一个访问的节点如果等于我的右子树的根,那我不就是根吗? 

 

class Solution {
public:vector<int> postorderTraversal(TreeNode* root){vector<int> v;stack<TreeNode*> s;TreeNode* cur = root;TreeNode* prev = nullptr;while(cur || !s.empty()){while(cur){s.push(cur);cur = cur->left;}TreeNode* top = s.top();if(top->right == nullptr || top->right == prev){   v.push_back(top->val);s.pop();prev = top;}elsecur = top->right;}return v;}};

 

下节预告 map和set 关注我 带你学习更多C++知识!!!! 

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

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

相关文章

Folx Pro 5 for Mac:极速下载神器,畅享无忧网络生活!

Folx Pro 5 for Mac是一款功能强大的下载管理器&#xff0c;它为用户提供了丰富的下载和管理功能&#xff0c;帮助用户更高效地管理网络下载任务。 首先&#xff0c;Folx Pro 5支持多线程下载&#xff0c;可以将下载任务分成多个线程&#xff0c;从而显著提高下载速度。这种多…

GLTFExporter是一个用于将3D场景导出为glTF格式的JavaScript库。

demo案例 GLTFExporter是一个用于将3D场景导出为glTF格式的JavaScript库。下面我将逐个讲解其入参、出参、属性、方法以及API使用方式。 入参&#xff08;Input Parameters&#xff09;: GLTFExporter的主要入参是要导出的场景对象和一些导出选项。具体来说&#xff1a; s…

Wi-Fi儿童故事机解决方案

一、方案描述 故事机是一套全新的数码幼教产品&#xff0c;是早期的复读机与mp3播放器结合的产物&#xff0c;其电路组成设有操作按键和微处理器控制的语音电路。它独有外放品质的儿童MP3&#xff0c;可以让宝宝赏音乐、听故事、学英语、习常识&#xff0c;帮助儿童发展语言能…

京东云免费服务器申请入口,2024年最新免费云主机

京东云服务器免费6月申请入口 jdyfwq.com 在京东云免费云主机申请页面&#xff0c;免费云服务器配置为云主机2核4G5M和轻量云主机2C2G可以申请免费使用&#xff0c;目前京东云免费云服务器申请时长从之前的6个月缩短到1个月&#xff0c;如下图&#xff1a; 京东云免费云主机 云…

2.java openCV4.x 入门-hello OpenCV

专栏简介 &#x1f492;个人主页 &#x1f4f0;专栏目录 点击上方查看更多内容 &#x1f4d6;心灵鸡汤&#x1f4d6;我们唯一拥有的就是今天&#xff0c;唯一能把握的也是今天建议把本文当作笔记来看&#xff0c;据说专栏目录里面有相应视频&#x1f92b; &#x1f9ed;文…

类和对象(下)--- 初始化列表、explicit、友元、static、匿名对象和内部类

本篇将会对类和对象的主要知识收尾&#xff0c;先会对构造函数进行补充&#xff0c;分别补充了构造函数体赋值、初始化列表、explicit 关键字&#xff0c;然后介绍 static 成员知识以及友元、内部类还有匿名对象等知识点&#xff0c;目录如下&#xff1a; 目录 1. 构造函数补充…

免费AI开源引擎:在电力电网工单系统中智能解析的应用场景

电力系统作为国家基础设施的重要组成部分&#xff0c;其稳定性和可靠性对经济社会发展具有至关重要的影响。随着智能电网技术的发展&#xff0c;如何高效、准确地处理电网工单&#xff0c;成为提升电网运维管理水平的关键。自然语言处理&#xff08;NLP&#xff09;技术在电力工…

想学电子维修,没基础怎么学?

如果你没有电子维修的基础&#xff0c;学习起来可能会有些挑战&#xff0c;但并不意味着不能学会。以下是一些建议&#xff0c;帮助你从零开始学习电子维修&#xff1a; 从了解基本概念 首先&#xff0c;要补充电子学的基本概念&#xff0c;比如电流、电压、电阻、电容、电感等…

扫码预约登记怎么做?表单二维码在线制作技巧

现在提交预约信息时&#xff0c;很多场景下已不再使用原来传统的纸质登记方式&#xff0c;而采用扫码填写信息的方式来登记预约信息。这种方式除了能够有效的降低成本之外&#xff0c;还能够让更多用户能够同时填写自己的信息&#xff0c;解决需要需要排队填写的复杂操作&#…

Clickhouse-表引擎探索之MergeTree

引言 前文曾说过&#xff0c;Clickhouse是一个强大的数据库Clickhouse-一个潜力无限的大数据分析数据库系统 其中一个强大的点就在于支持各类表引擎以用于不同的业务场景。 MergeTree MergeTree系列的引擎被设计用于插入极大量的数据到一张表当中。数据可以以数据片段的形式一…

kubernetes用户权限管理详解——普通用户[kubeconfig]

原文&#xff1a; 学一下https://suxueit.com/article_detail/tdVymI4BWZdDRfKqnv1y K8s 的用户分为两类 普通用户&#xff1a;普通用户是指集群外部的人或系统管理&#xff0c;它们不由 Kubernetes 直接管理。普通用户的证书、密钥和权限管理通常由外部系统&#xff08;如企业…

科创新格局·共赢双循环“2024上海智能科技与创新展览会”

2024上海智能科技与创新展览会&#xff0c;将于6月中旬在上海新国际博览中心隆重召开。作为一场盛大的科技盛会&#xff0c;此次展览会将汇聚科技前瞻趋势&#xff0c;融合产业贸易优势&#xff0c;布局初创投资赛道&#xff0c;提供全方位场景生态的跨界合作&#xff0c;构建“…