1.根据二叉树创建字符串

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

class Solution {public:void _tree2str(TreeNode* root, string& str){if(root==nullptr)//为空直接返回{return;}if(root->left&& root->right)//左右子树均不为空 {str += to_string(root->val);str += "(";_tree2str(root->left, str);str += ")";str += "(";_tree2str(root->right, str);str += ")";}else if(root->left == nullptr){if(root->right)//左子树为空,右子树不空{str += to_string(root->val);str += "()";str += "(";_tree2str(root->right, str);str += ")";}else//左右子树都空{str += to_string(root->val);}}else//左子树不为空,右子树为空{str += to_string(root->val);str += "(";_tree2str(root->left, str);str += ")";}}string tree2str(TreeNode* root) {string s;_tree2str(root, s);//调用子函数return s;}
};

2.二叉树的层序遍历

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

class Solution {public:vector<vector<int>> levelOrder(TreeNode* root) {vector<vector<int>> vv;queue<TreeNode*> q;if(root == nullptr)//空树直接返回{return vv;}q.push(root);//不为空 队列q用来存放每一层的节点指针int levelSize = 1;//每层的节点个数,最开始肯定是1while(!q.empty())//队列不为空就继续{vector<int> v;while(levelSize--)//节点个数是几,v就插入几次{TreeNode* front = q.front();//先把第一个节点指针保存下来,然后将该节点从队列删除v.push_back(front->val);q.pop();//接下来判断刚刚删除的节点的左右孩子是否为空,不为空就插入到队列if(front->left){q.push(front->left);}if(front->right){q.push(front->right);}}levelSize = q.size();//更新下一层要插入的次数vv.push_back(v);}return vv;}
};

3.二叉树的层序遍历(自底向上)

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

该题和上题类似,只需要逆置一下vv里面的vector v,我们直接上代码

class Solution {public:vector<vector<int>> levelOrderBottom(TreeNode* root) {vector<vector<int>> vv;queue<TreeNode*> q;if(root == nullptr){return vv;}q.push(root);int levelSize = 1;while(!q.empty()){vector<int> v;while(levelSize--){TreeNode* front = q.front();v.push_back(front->val);q.pop();if(front->left){q.push(front->left);}if(front->right){q.push(front->right);}}levelSize = q.size();vv.push_back(v);}reverse(vv.begin(), vv.end());return vv;}
};

4.二叉树的最近公共祖先

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

class Solution {public:bool FindNode(TreeNode* root, TreeNode* x, stack<TreeNode*>& st){if(root == nullptr)//root为空返回false{return false;}st.push(root);//不为空先把当前节点插入栈中,或许这个节点是目标节点的一个祖先,也有可能不是,那就需要我们在后面再将其pop掉if(root == x)//找到了返回true{return true;}if(FindNode(root->left, x, st))//在左子树找到了返回true{return true;}if(FindNode(root->right, x, st))//在右子树找到了返回true{return true;}//到这里,说明我们插入的root不是目标节点的祖先,将其pop掉st.pop();return false;}TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {stack<TreeNode*> st1, st2;//定义两个栈用于保存查找目标节点过程中所有祖先节点//查找目标节点FindNode(root, p, st1);  FindNode(root, q, st2);//此时st1里面都是p的祖先,st2里面都是q的祖先。//我们假定st1.size()更大,如果不是这样在将其长短交换stack<TreeNode*> longSt = st1;stack<TreeNode*> shortSt = st2;if(longSt.size()<shortSt.size()){swap(longSt, shortSt);}//先让长的栈走差距步while(longSt.size()>shortSt.size()){longSt.pop();}//此时两个栈一样长,从顶部开始依次比较,直到第一次相等,此时找到了最近的公共祖先while(longSt.top() != shortSt.top()){longSt.pop();shortSt.pop();}return longSt.top();}
};

5.二插搜索树与双向链表

二叉搜索树与双向链表_牛客题霸_牛客网 (nowcoder.com)

class Solution {//该题显然是用到了中序遍历
public:void InOrder(TreeNode* root, TreeNode*& prev){if(root==nullptr)//root为空直接返回{return;}InOrder(root->left, prev);//不为空先对左子树遍历root->left = prev;//左子树遍历之后,将prev赋给leftif(prev)//如果prev不为空,说明他是上一次的root,上面的那行代码只解决了前驱指针,而在这里我们解决了上一次的root的后继指针的问题。{prev->right = root;}prev = root;//更新prevInOrder(root->right, prev);//中序遍历右子树}TreeNode* Convert(TreeNode* pRootOfTree) {if(pRootOfTree == nullptr){return nullptr;}TreeNode* prev = nullptr;//前驱指针 初识为空,也就是图上4的left为空InOrder(pRootOfTree, prev);//中序遍历TreeNode* head = pRootOfTree;//找头,找到最左面的节点while(head->left){head = head->left;}return head;}

6.从前序与中序遍历序列构造二叉树

105. 从前序与中序遍历序列构造二叉树 - 力扣(LeetCode)

class Solution {public:TreeNode* _buildTree(vector<int>& preorder, vector<int>& inorder, int& pi, int inbegin, int inend){if(inbegin>inend)//说明该树为空直接return{return nullptr;}TreeNode* root = new TreeNode(preorder[pi]);//不为空建树 ,通过前序建树,通过中序找区间pi++;int rooti = inbegin;while(rooti<=inend){if(root->val == inorder[rooti])//在中序找到值与root->val相等的下标{break;}else{rooti++;}}//[inbegin, rooti-1][rooti][rooti+1, inend]root->left = _buildTree(preorder, inorder, pi, inbegin, rooti-1);root->right = _buildTree(preorder, inorder, pi, 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);}
};
//注意pi必须用& 保证全局只有一个pi  否则会出错

7.从中序与后序遍历序列构造二叉树

106. 从中序与后序遍历序列构造二叉树 - 力扣(LeetCode)

该题与上题类似,思路大体相同,不同之处在于这道题需要后序来确定根,因为后序是左右根, 所以我们从后序的最后一个值开始建树,并且建好根之后先建右子树,再建左子树。

class Solution {public:TreeNode* _buildTree(vector<int>& inorder, vector<int>& postorder, int& pi, int inBegin, int inEnd){if(inBegin > inEnd){return nullptr;}TreeNode* root = new TreeNode(postorder[pi]);pi--;int rooti = inBegin;while(rooti <= inEnd){if(root->val == inorder[rooti]){break;}else{rooti++;}}//[inBegin,rooti-1][rooti][rooti+1, inEnd]root->right = _buildTree(inorder, postorder, pi, rooti+1, inEnd);root->left = _buildTree(inorder, postorder, pi, inBegin, rooti-1);return root;}TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) {int i = postorder.size()-1;return _buildTree(inorder, postorder, i, 0, inorder.size()-1);}
};

8.二叉树的前序遍历(非递归)

144. 二叉树的前序遍历 - 力扣(LeetCode)

class Solution {public:vector<int> preorderTraversal(TreeNode* root) {TreeNode* cur = root;stack<TreeNode*> st;vector<int> ret;while(cur || !st.empty())//循环条件可以先空着我们之后在分析{while(cur)//先访问左路节点,并将左路节点入栈{ret.push_back(cur->val);st.push(cur);cur = cur->left;}TreeNode* top = st.top();//top取栈顶元素,然后删除栈顶st.pop();cur = top->right;//此时左路节点已经访问晚了, 去访问他的右子树。cur指向谁,就表示开始前序遍历哪个树//现在我们可以控制循环的条件 :1.cur不为空,说明此时cur指的树的左路节点没有访问完//                          2.st不为空,说明左路节点的右子树还没有访问完}return ret;}
};

9.二叉树的中序遍历(非递归)

94. 二叉树的中序遍历 - 力扣(LeetCode)

//该题和上题类似我们直接上代码
class Solution {public:vector<int> inorderTraversal(TreeNode* root) {stack<TreeNode*> st;vector<int> ret;TreeNode* cur = root;while(cur || !st.empty()){while(cur)//cur不为空左路节点入栈{st.push(cur);cur = cur->left;}TreeNode* top = st.top();//取出栈顶,并pop掉st.pop();ret.push_back(top->val);cur = top->right;//cur指向top节点的右子树}return ret;}
};

10.二叉树的后序遍历(非递归)

145. 二叉树的后序遍历 - 力扣(LeetCode)

//该题也和前面两题类似
class Solution {public:vector<int> postorderTraversal(TreeNode* root) {vector<int> ret;stack<TreeNode*> st;TreeNode* cur = root;TreeNode* prev = nullptr;//用来记录上一次插入的节点while(cur || !st.empty()){while(cur)//左路节点入栈{st.push(cur);cur = cur->left;}TreeNode* top = st.top();//去栈顶元素if(top->right == nullptr || top->right == prev)//如果top->right为空或者top->right为上一次插入的节点,就说明可以插入当前值{st.pop();ret.push_back(top->val);prev = top;}else//否则,访问右子树{cur = top->right;}}return ret;}
};

l

c++逆天改命进阶--二叉树练习题相关推荐

  1. c++逆天改命进阶--AVLTree

    1.AVL树的概念 二叉搜索树虽可以缩短查找的效率,但如果数据有序或接近有序二叉搜索树将退化为单支树,查找元素相当于在顺序表中搜索元素,效率低下.因此,两位俄罗斯的数学家G.M.Adelson-Vel ...

  2. c++逆天改命进阶--RedBlackTree

    1.红黑树的概念 红黑树,是一种二叉搜索树,但在每个结点上增加一个存储位表示结点的颜色,可以是Red或Black. 通过对任何一条从根到叶子的路径上各个结点着色方式的限制,红黑树确保没有一条路径会比其 ...

  3. c++逆天改命进阶--多态

    1.多态的概念 多态的概念:通俗来说,就是多种形态,具体点就是去完成某个行为,当不同的对象去完成时会产生出不同的状态. 举个栗子:比如买票这个行为,当普通人买票时,是全价买票:学生买票时,是半价买票: ...

  4. c++逆天改命进阶--继承

    1.继承 1.1继承的概念 继承(inheritance)机制是面向对象程序设计使代码可以复用的最重要的手段,它允许程序员在保持原有类特 性的基础上进行扩展,增加功能,这样产生新的类,称派生类.继承呈 ...

  5. c++逆天改命进阶--哈希表

    1.unordered系列关联式容器 在C++98中,STL提供了底层为红黑树结构的一系列关联式容器,在查询时效率可达到 ,即最差情况下需要比较红黑树的高度次,当树中的节点非常多时,查询效率也不理想. ...

  6. c++逆天改命进阶--map_set

    1.关联式容器 我们已经接触过STL中的部分容器,比如:vector.list.deque.forward_list(C++11)等,这些容器统称为序列式容器,因为其底层为线性序列的数据结构,里面存储 ...

  7. 我出书了,《逆天改命——程序员成神之路》开源,从业十年大厂技术专家的一百条人生建议,建议收藏

    大家好,我是启舰 我有本出版社约稿的书<逆天改命--程序员成神之路>,最终决定放弃出版社合作,开源给大家. 这本书集合了我从业十来年的经验结晶,希望能够帮到大家. 我在上学和工作期间,也总 ...

  8. 一份让HR都震撼的简历:从中专生逆袭到985硕士,逆天改命!网友:这才是真正的人才!

    这是一份极其励志的简历,一位很神奇的求职者. 一位hr说,初看学历是985硕士,以为是一位学霸,没想到顺着往下看,越看越惊讶,很敬佩这位有毅力的候选人. 下面就是这份让hr都为之敬佩的简历: 网友感叹 ...

  9. 逆天改命,机械飞升:渐冻症科学家拒绝等死,将自己改造成了「半机械人」...

    点击上方"AI遇见机器学习",选择"星标"公众号 重磅干货,第一时间送达 来自:机器之心 作为人类的 Scott-Morgan 已经死去,未来的 Scott-M ...

最新文章

  1. IMX51---GPIO
  2. Apache启动过程(PHP_MINIT_FUNCTION的调用)
  3. 138. 复制带随机指针的链表 golang
  4. iOS 横竖屏切换解决方案
  5. 命令行快速部署Exchange2010
  6. android 沙盒 ios,iOS中的沙盒机制
  7. IIS7.5应用程序池集成模式和经典模式的区别介绍
  8. 驻马店远大计算机阳业学院,电力学院
  9. 供应IMX335/IMX386/IMX258/OV4689/OV5640/OV8865/光学防抖摄像头模组
  10. 魔兽争霸修改器,局域网内使用!防封号!!!!!!!!
  11. 数据结构视频教程 -《吉大刘大有主讲》
  12. SaaSpace:11种最佳免费会计软件工具
  13. python爬取网易云音乐评论并制作词云
  14. 一个屌丝程序猿的人生(二十七)
  15. Unity 组合键输入及容易忽略的问题
  16. 花朵藤条植物生长动画婚礼视频标题pr模板
  17. 使用umiJs搭建前端项目添加背景图片
  18. 展锐android r kernel 快速编译
  19. 为什么某些Win32技术在Windows NT服务中行为不当?
  20. 偏振器件传输矩阵matlab编程,偏振器件的琼斯矩阵

热门文章

  1. pycharm环境下导入包
  2. Oracle Primavera Unifier文档管理器(Document Manager)
  3. 相敏检波电路matlab,一种消除分布电容影响的电阻测量方法
  4. 第十七届全国大学生智能汽车竞赛百度创意组来啦
  5. 仿淘宝购物车demo---增加和减少商品数量
  6. HTML配色工具!在线配色工具
  7. Linux主机安全加固方法使用开源软件fail2ban防护主机
  8. 联通云OSS上传文件
  9. allegro如何快设置快捷键旋转器件
  10. Android手机模拟器旋转快捷键