BST中序遍历(Iterative)
首先来看下 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)相关推荐
- LeetCode Kth Smallest Element in a BST(中序遍历)
问题:给出一个二叉查找树,求第k小的数 思路:第一种方式是使用递归中序遍历得到结果后,直接取第k个数即可 第二种方式是使用非递归中序遍历,在得到第k个数后直接停止 具体代码参考: https://gi ...
- 程序员面试金典 - 面试题 17.12. BiNode(BST中序遍历)
1. 题目 二叉树数据结构TreeNode可用来表示单向链表(其中left置空,right为下一个链表节点). 实现一个方法,把二叉搜索树转换为单向链表,要求值的顺序保持不变,转换操作应是原址的,也就 ...
- sdut 2128 树结构练习——排序二叉树(BST)的中序遍历
树结构练习--排序二叉树的中序遍历 Time Limit: 1000MS Memory Limit: 65536KB Submit Statistic Discuss Problem Descript ...
- LeetCode 98. Validate Binary Search Tree--C++解法--判断是否是BST--递归,迭代做法,中序遍历
LeetCode 98. Validate Binary Search Tree–C++解法–判断是否是BST–递归,迭代做法,中序遍历 LeetCode题解专栏:LeetCode题解 LeetCod ...
- 74. Leetcode 501. 二叉搜索树中的众数 (二叉搜索树-中序遍历类)
给你一个含重复值的二叉搜索树(BST)的根节点 root ,找出并返回 BST 中的所有 众数(即,出现频率最高的元素).如果树中有不止一个众数,可以按 任意顺序 返回.假定 BST 满足如下定义:结 ...
- Algorithms_二叉树的前序遍历、中序遍历、后续遍历(深度优先)
文章目录 前序.中序.后序的含义 实例 Code (递归) 前序遍历 中序遍历 后序遍历 测试 Code (非递归) 前序.中序.后序的含义 前序遍历: 先输出父节点,再遍历左子树,最后遍历右子树 中 ...
- 二叉排序树的中序遍历规律_看懂这篇文章,玩转二叉查找树
所谓二叉查找树,就是按照二分进行查找,每次查询只需要选择其中一个子树就进行查找,从而减少查找次数,提升查询效率! 一.介绍 在前面的文章中,我们对树这种数据结构做了一些基本介绍,今天我们继续来聊聊一种 ...
- LeetCode 501. 二叉搜索树中的众数(中序遍历)
文章目录 1. 题目 2. 中序遍历 1. 题目 给定一个有相同值的二叉搜索树(BST),找出 BST 中的所有众数(出现频率最高的元素). 假定 BST 有如下定义: 结点左子树中所含结点的值小于等 ...
- LeetCode 173. 二叉搜索树迭代器(中序遍历)
文章目录 1. 题目信息 2. 二叉树中序遍历 1. 题目信息 实现一个二叉搜索树迭代器.你将使用二叉搜索树的根节点初始化迭代器. 调用 next() 将返回二叉搜索树中的下一个最小的数. 示例: B ...
- 区间dp——cf1025D二叉搜索树的中序遍历好题!
这题帮我复习了一下BST的中序遍历.. 因为给定的数组是递增的,那么BST的中序遍历一定是1 2 3 4 5 6 7 8 9 ... n 即[l,r]为左子树,那么根节点就是r+1,反之根节点就是l- ...
最新文章
- **kw传参一个重要的细节
- 云炬Android开发笔记 5-9,10拦截器功能设计与实现
- 14_面向对象API绘图、图中图 (A Plot inside of Another Plot)、设定绘图范围Setting the Plot Range、对数尺度Logarithmic Scale
- fork vfork exit _exit (转)
- 阿里合伙人程立:阿里15年,我撕掉了身上两个标签
- 最好的git教程_最好的Git教程
- 静态文件之static+url控制系统(萌新笔记)
- 【图解】QT 布局、 sizeHint和SizePolicy概念
- 三层交换机静态路由VLAN配置实例(华为)
- [运放滤波器]1_理想运放_虚短虚断
- Datawhale线上组队学习汇总
- PS 工具获取:Photoshop CS6超级免安装精简版来临!不到200M!
- 十大管理之项目进度管理知识点
- 三自由度机械手腕设计机构设计
- 心知天气api PHP,心知天气API的应用实例
- 计算机的配件知识,最基本的入门知识:电脑由哪些部件组成?
- C#如何遍历文件夹下的所有文件
- 最后期限Lite,兴趣社区圈子论坛小程序前后端
- Pro10丨枢轴点反转策略
- Chart.js入门:简介