头文件: 用到的是前序遍历中的头文件,具体可参见 "二叉树的前序遍历"

一,中序遍历的概念

中序遍历
                按照 左儿子-根节点-右儿子 的顺序访问二叉树

方式
                1,递归遍历
                2,栈迭代遍历 (借助栈结构)
                3,Morris 遍历 (栈迭代的基础上优化空间复杂度)

二,递归遍历

/*
递归遍历先访问当前节点的左子树,然后再访问当前节点,最后访问当前节点的右子树T : O(n),n 是二叉树的节点数,每个节点恰好被遍历1次S : O(n), 递归过程中的栈开销,平均情况下为 O(log n),最坏情况下树为链状,为 O(n)
*/
void inTraverse(TreeNode* root, vector<int>& vec) {if (root) {inTraverse(root->left, vec); // 访问当前节点的左子树vec.emplace_back(root->val);    // 访问当前节点inTraverse(root->right, vec);   // 访问当前节点的右子树}
}

三,栈迭代遍历

/*
栈迭代遍历1,因为中序遍历是先访问左子树,所以我们应该一直将当前节点的左子树加入到栈中,直道当前节点没有左子树。2,因为当前节点没有左子树,所以当前节点就相当于是一个没有左子树的根节点,从栈中弹出,访问当前节点。3,然后当前节点指向右子树,继续步骤1。时间复杂度:O(n),其中 n 为二叉树节点的个数。二叉树的遍历中每个节点会被访问一次且只会被访问一次。空间复杂度:O(n),空间复杂度取决于栈深度,而栈深度在二叉树为一条链的情况下会达到 O(n) 的级别。
*/
void inTraverseN(TreeNode* root, vector<int>& vec) {stack<TreeNode *> stack;while (root || !stack.empty()) {    // 只要栈未空,或当前节点不是空节点while (root) {        // 一直将当前节点的左子树加入到栈中,循环结束时,栈顶元素是没有左子树的stack.emplace(root);root = root->left;}root = (TreeNode*)stack.top();    // 弹出栈顶元素,此时栈顶节点就相当于是一个没有左子树的根节点stack.pop();vec.emplace_back(root->val); // 访问它root = root->right;       // 让当前节点指向右子树}
}

四,Morris 遍历

/*
Morris 遍历模版与前序遍历相同,只是要思考,在什么时候去访问该节点 ?1,当前节点没有左子树时,当前节点就相当于没有左子树的根节点,此时需要访问它。2,当前节点有左子树,但是左子树的最右节点已经指向了当前节点,说明当前节点的整个左子树已经遍历结束了,此时也需要访问当前节点。T : O(n),其中 n 是二叉树的节点数。没有左子树的节点只被访问一次,有左子树的节点被访问两次。S : O(1), 只操作已经存在的指针(树的空闲指针),因此只需要常数的额外空间。
*/
void inTraverseM(TreeNode* root, vector<int>& vec) {TreeNode* cur = root;TreeNode* mostRight = nullptr;while (cur) {mostRight = cur->left;if (mostRight) {while (mostRight->right && mostRight->right != cur) {mostRight = mostRight->right;}if (mostRight->right == nullptr) {mostRight->right = cur;cur = cur->left;}else{vec.emplace_back(cur->val);  // ## 当最右节点的右子树指向了 cur,说明整个左子树都遍历完了,此时 cur 就是根节点,访问它,然后遍历右子树mostRight->right = nullptr;cur = cur->right;}}else {vec.emplace_back(cur->val);      // ## 当没有左子树的时候,当前节点就相当于一个没有左子树的根节点,需要访问它cur = cur->right;}}
}

五,主函数

void inOrderTraversal(TreeNode* root) {vector<int> ret;inTraverse(root, ret);cout << "中序遍历, 递归 : " << endl;PRINT(ret);ret.clear();inTraverseN(root, ret);cout << "中序遍历, 栈迭代 : " << endl;PRINT(ret);ret.clear();inTraverseM(root, ret);cout << "中序遍历, Morris : " << endl;PRINT(ret);
}#if IN_ORDER_TRAVERSALint main() {TreeNode* root = getRandomTree();inOrderTraversal(root);return 0;
}
#endif

2. 二叉树的中序遍历 (inOrder)相关推荐

  1. 15 二叉树的中序遍历(Binary Tree Inorder Traversal)

    文章目录 1 题目 2 描述 3 解决方案 3.1 递归算法 3.1.1 遍历法(Traverse) 思路 源码 3.1.2 分治法(Devide And Conquer) 思路 源码 3.2 非递归 ...

  2. 《LeetCode力扣练习》第94题 二叉树的中序遍历 Java

    <LeetCode力扣练习>第94题 二叉树的中序遍历 Java 一.资源 题目: 给定一个二叉树的根节点 root ,返回它的 中序 遍历. 示例 1: 输入:root = [1,nul ...

  3. 树结构练习——排序二叉树的中序遍历(二叉搜索树)

    树结构练习--排序二叉树的中序遍历 Time Limit: 1000MS Memory limit: 65536K 题目描述 在树结构中,有一种特殊的二叉树叫做排序二叉树,直观的理解就是--(1).每 ...

  4. lintcode:二叉树的中序遍历

    题目: 二叉树的中序遍历 给出一棵二叉树,返回其中序遍历 样例 给出二叉树 {1,#,2,3}, 1\2/3 返回 [1,3,2]. 挑战 你能使用非递归算法来实现么? 解题: 程序直接来源 Java ...

  5. 二叉树的中序遍历_Go 刷 leetcode从前序与中序遍历序列构造二叉树

    今天为大家讲解 LeetCode 第 105 题,是一道关于数组和树的题目. 题目描述 根据一棵树的前序遍历与中序遍历构造二叉树. 注意: 你可以假设树中没有重复的元素. 例如,给出 前序遍历 pre ...

  6. LeetCode-94. 二叉树的中序遍历

    题目描述: 给定一个二叉树的根节点 root ,返回它的 中序 遍历. 输入:root = [1,null,2,3] 输出:[1,3,2] 思路分析: 用递归或是迭代算法来解决. 递归: 首先我们需要 ...

  7. 前序遍历 (preorder traversal) - 中序遍历 (inorder traversal) - 后序遍历 (postorder traversal)

    前序遍历 (preorder traversal) - 中序遍历 (inorder traversal) - 后序遍历 (postorder traversal) 1. 前序遍历 (preorder ...

  8. 94. 二叉树的中序遍历

    94. 二叉树的中序遍历 难度中等902收藏分享切换为英文接收动态反馈 给定一个二叉树的根节点 root ,返回它的 中序 遍历. 示例 1: 输入:root = [1,null,2,3] 输出:[1 ...

  9. C语言实现二叉树的中序遍历

    二叉树是一种重要的数据结构,对二叉树的遍历也很重要.这里简单介绍三种二叉树中序遍历的方法.二叉树的中序遍历就是首先遍历左子树,然后访问当前节点,最后遍历右子树.对于下面的二叉树,中序遍历结果如下: 结 ...

最新文章

  1. rabbitmq学习——安装测试
  2. 使用hyperopt(Bayesian optimization)为xgboost模型挑选最优参数进行模型构建、by Cross Validation
  3. shell字符串的处理
  4. Initializing libiomp5md.dll, but found libiomp5md.dll already initialized.
  5. Stm 32 IAP 在线 升级IAP 的 操作
  6. python面向对象编程(封装与继承)
  7. linux centos7 安装redis
  8. 安卓手机 python控制_PyAndroidControl:使用python脚本控制你的安卓设备
  9. HashMap和Hashtable的区别--List,Set,Map等接口是否都继承自Map接口--Collection和Collections的区别...
  10. 固定权重 关于Mxnet的一些基础知识理解(1)
  11. Hibernate获取'上一条'和'下一条'记录
  12. 项目的升级-给RemoveButterKnife插件增加新功能
  13. window10计算机策略,Win10秘笈:重置组策略/安全策略命令大全
  14. Typora自制主题
  15. 为什么docker的端口映射需要开启ip转发功能?
  16. 2021毓英中学高考成绩查询,泉州知名中学2020高考成绩喜报龙虎榜
  17. NSIS 头文件介绍_WordFunc.nsh(3)
  18. 用scrapy+selenium+Firefox爬取腾讯新闻
  19. ◮OpenGL-混合
  20. android最佳开发实现_在android开发中使用可访问性最佳做法

热门文章

  1. 爬链家数据(武汉光谷房价)
  2. QuantLib 金融计算库
  3. 移动端h5 页面底部有一条白线的解决方案
  4. MS Access 与 Excel区别与各自的优势
  5. python到pandas_Python-Pandas
  6. 小说形象特征包括哪些方面_小说形象特征包括哪些方面
  7. 0型系统, I型系统, II型系统对PID的影响
  8. Java设计模式吐血整理
  9. 设计模式 之 责任链模式
  10. #228. 噼里啪啦