首先来看下 recursive 的版本:

    void inorder(TreeNode* node) {if (node != NULL) {inorder(node->left);  //左子树print(node->val);  //当前节点inorder(node->right);  //右子树}}

如何将此版本转化成iterative的?

1. 参考Inorder Binary Tree Traversal (Iteratively)

说白了就是跑一遍程序,看看它是如何运行的。
比如

           5/   \
       3       7/   \   /   \
    1     4 6     8

中序:1,3,4,5,6,7,8
用TreeNode *p来代表当前处理的node。bool done代表是否完成。

如果当前节点p不为空,处理其左子树;如果为空,说明上轮迭代的p需要弹出来,因为左子树(为空)已经处理完了。(当然p为空也有可能是p指向的右子树为空,那说明p的整个函数都跑完了。)
弹出node之后,就要考虑它的右子树,所以把当前需要处理的节点设为弹出来的node的right,处理它的右子树。
请记住,被弹出栈的元素就被打印出来了,也就是已遍历了。
代码如下:

    void inorder(TreeNode* root) {stack<TreeNode*> st;bool done = false;TreeNode* p = root;while (done == false) {if (p != NULL) {st.push(p);p = p->left;  //处理左子树} else {if (st.empty()) {done = true;break;}TreeNode* node = st.top();print(node);  //此节点st.pop();p = node->right;  //处理右子树}}}

2. 参考Help me understand Inorder Traversal without using recursion

stackoverflow中回答的第一条说,可以把recursion版的代码直接翻译成iteration版的代码
我们先做第一步:
把尾递归改成循环

    void inorder(TreeNode* root) {TreeNode* p = root;while (p != NULL) {inorder(p->left);print(p);p = p->right;}}

然后将中间的递归改写(用stack)

    void inorder(TreeNode* root) {stack<TreeNode*> st;TreeNode* p = root;while (p != NULL || !st.empty()) {if (p != NULL) {st.push(p);p = p->left;} else {TreeNode* node = st.top();st.pop();print(node);p = node->right;}}}

个人觉得这个

while (p != NULL || !st.empty()) 

其实也可以理解为原递归函数的两个出口就是
1. node 为 NULL
2. 栈帧空了

3. leetcode新题:

Binary Search Tree Iterator
此题将传统的中序遍历非递归 人为地拆开。
值得思考:
1. 如何拆
2. next()复杂度降到:平均时间O(1), 空间O(h), h为树高
3. 为什么平均时间为O(1), 空间为O(h)
4. c++ map的底层实现??

代码:

class BSTIterator {
private:stack<TreeNode*> st;TreeNode *node;
public:BSTIterator(TreeNode *root) {node = root;while (node != NULL) {st.push(node);node = node->left;}}/** @return whether we have a next smallest number */bool hasNext() const{if (node == NULL && st.empty()) return false;return true;}/** @return the next smallest number */int next() {while (node != NULL) {st.push(node);node = node->left;}TreeNode *willpop = st.top();st.pop();node = willpop->right;return willpop->val;}
};

时间:降到O(1)的原因在于,遍历本身的时间是O(n),有n个节点,自然每个节点的时间是O(1)。空间:st的空间就是所用的存储空间,因此是树高,假设st一次开满的话,那么就要开树高那么多空间,就是说最大是树高。

BST中序遍历(Iterative)相关推荐

  1. LeetCode Kth Smallest Element in a BST(中序遍历)

    问题:给出一个二叉查找树,求第k小的数 思路:第一种方式是使用递归中序遍历得到结果后,直接取第k个数即可 第二种方式是使用非递归中序遍历,在得到第k个数后直接停止 具体代码参考: https://gi ...

  2. 程序员面试金典 - 面试题 17.12. BiNode(BST中序遍历)

    1. 题目 二叉树数据结构TreeNode可用来表示单向链表(其中left置空,right为下一个链表节点). 实现一个方法,把二叉搜索树转换为单向链表,要求值的顺序保持不变,转换操作应是原址的,也就 ...

  3. sdut 2128 树结构练习——排序二叉树(BST)的中序遍历

    树结构练习--排序二叉树的中序遍历 Time Limit: 1000MS Memory Limit: 65536KB Submit Statistic Discuss Problem Descript ...

  4. LeetCode 98. Validate Binary Search Tree--C++解法--判断是否是BST--递归,迭代做法,中序遍历

    LeetCode 98. Validate Binary Search Tree–C++解法–判断是否是BST–递归,迭代做法,中序遍历 LeetCode题解专栏:LeetCode题解 LeetCod ...

  5. 74. Leetcode 501. 二叉搜索树中的众数 (二叉搜索树-中序遍历类)

    给你一个含重复值的二叉搜索树(BST)的根节点 root ,找出并返回 BST 中的所有 众数(即,出现频率最高的元素).如果树中有不止一个众数,可以按 任意顺序 返回.假定 BST 满足如下定义:结 ...

  6. Algorithms_二叉树的前序遍历、中序遍历、后续遍历(深度优先)

    文章目录 前序.中序.后序的含义 实例 Code (递归) 前序遍历 中序遍历 后序遍历 测试 Code (非递归) 前序.中序.后序的含义 前序遍历: 先输出父节点,再遍历左子树,最后遍历右子树 中 ...

  7. 二叉排序树的中序遍历规律_看懂这篇文章,玩转二叉查找树

    所谓二叉查找树,就是按照二分进行查找,每次查询只需要选择其中一个子树就进行查找,从而减少查找次数,提升查询效率! 一.介绍 在前面的文章中,我们对树这种数据结构做了一些基本介绍,今天我们继续来聊聊一种 ...

  8. LeetCode 501. 二叉搜索树中的众数(中序遍历)

    文章目录 1. 题目 2. 中序遍历 1. 题目 给定一个有相同值的二叉搜索树(BST),找出 BST 中的所有众数(出现频率最高的元素). 假定 BST 有如下定义: 结点左子树中所含结点的值小于等 ...

  9. LeetCode 173. 二叉搜索树迭代器(中序遍历)

    文章目录 1. 题目信息 2. 二叉树中序遍历 1. 题目信息 实现一个二叉搜索树迭代器.你将使用二叉搜索树的根节点初始化迭代器. 调用 next() 将返回二叉搜索树中的下一个最小的数. 示例: B ...

  10. 区间dp——cf1025D二叉搜索树的中序遍历好题!

    这题帮我复习了一下BST的中序遍历.. 因为给定的数组是递增的,那么BST的中序遍历一定是1 2 3 4 5 6 7 8 9 ... n 即[l,r]为左子树,那么根节点就是r+1,反之根节点就是l- ...

最新文章

  1. **kw传参一个重要的细节
  2. 云炬Android开发笔记 5-9,10拦截器功能设计与实现
  3. 14_面向对象API绘图、图中图 (A Plot inside of Another Plot)、设定绘图范围Setting the Plot Range、对数尺度Logarithmic Scale
  4. fork vfork exit _exit (转)
  5. 阿里合伙人程立:阿里15年,我撕掉了身上两个标签
  6. 最好的git教程_最好的Git教程
  7. 静态文件之static+url控制系统(萌新笔记)
  8. 【图解】QT 布局、 sizeHint和SizePolicy概念
  9. 三层交换机静态路由VLAN配置实例(华为)
  10. [运放滤波器]1_理想运放_虚短虚断
  11. Datawhale线上组队学习汇总
  12. PS 工具获取:Photoshop CS6超级免安装精简版来临!不到200M!
  13. 十大管理之项目进度管理知识点
  14. 三自由度机械手腕设计机构设计
  15. 心知天气api PHP,心知天气API的应用实例
  16. 计算机的配件知识,最基本的入门知识:电脑由哪些部件组成?
  17. C#如何遍历文件夹下的所有文件
  18. 最后期限Lite,兴趣社区圈子论坛小程序前后端
  19. Pro10丨枢轴点反转策略
  20. Chart.js入门:简介

热门文章

  1. urchin.js作用以及urchin.js注释
  2. volatile内存屏障
  3. Quantile g-computation的介绍及R实现
  4. Arduino NBIoT使用方法一
  5. 浅谈几个倾斜摄影三维模型的修补软件
  6. 《Loy解说Eureka客户端源码(一)》
  7. [20150818]模拟wan网络延迟.txt
  8. MemoryCache缓存help类
  9. 阿里无影云电脑 试用评测
  10. java实现pdf 转 高清图片