Binary Search Tree Iterator(中序遍历)

  1. 题意
  2. 分析
  3. 代码

题目

题意

写一个二叉搜索树的迭代器,包括初始化、next()和hasNext()操作,要求平摊时间复杂度为O(1),空间复杂度为O(h)

分析

因为空间复杂度是O(h),所以肯定不能把整个树直接存成一个数组然后直接查找,而是要利用树的性质。与所有遍历一样,中序遍历的实质功能也可理解为,为所有节点赋予一个次序,从而将半线性的二叉树转化为线性结构。于是一旦指定了遍历策略,即可与向量和列表一样,在二叉树的节点之间定义前驱与后继关系。其中没有前驱(后继)的节点称作首(末)节点。

对于后继的查找,共分两大类情况。若当前节点有右孩子,则其直接后继必然存在,且属于其右子树。此时只需转入右子树,再沿该子树的最左侧通路朝左下方深入,直到抵达子树中最靠左(最小)的节点。

反之,若当前节点没有右子树,则若其直接后继存在, 必为该节点的某一祖先,且是将当前节点纳入其左子树的最低祖先。于是首先沿右侧通路朝左上方上升,当不能继续前进时,再朝右上方移动一步即可。

作为后一情况的特例,出口时s可能为NULL。这意味着此前沿着右侧通路向上的回溯,抵达了树根。也就是说,当前节点是全树右侧通路的终点——它也是中序遍历的终点,没有后继。

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
/**
* Definition for binary tree
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class BSTIterator {
public:
stack<TreeNode *> s;
void addToStack(TreeNode * root){
while(root){
s.push(root);
root=root->left;
}
}

BSTIterator(TreeNode *root) {
addToStack(root);
}

/** @return whether we have a next smallest number */
bool hasNext() {
return s.size()>0;
}

/** @return the next smallest number */
int next() {
int res = s.top()->val;
TreeNode * top = s.top();
s.pop();
if(top-> right){
addToStack(top->right);
}

return res;
}
};

/**
* Your BSTIterator will be called like this:
* BSTIterator i = BSTIterator(root);
* while (i.hasNext()) cout << i.next();
*/

转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 yxhlfx@163.com

文章标题:Binary Search Tree Iterator(中序遍历)

本文作者:红尘追风

发布时间:2015-01-10, 10:26:46

原始链接:http://www.micernel.com/2015/01/10/BinarySearchTreeIterator/

版权声明: "署名-非商用-相同方式共享 4.0" 转载请保留原文链接及作者。

目录