• Binary Search Tree Iterator

Binary Search Tree Iterator

Implement an iterator over a binary search tree (BST). Your iterator will be initialized with the root node of a BST. Calling next() will return the next smallest number in the BST. Note: next() and hasNext() should run in average O(1) time and uses O(h) memory, where h is the height of the tree. 题目翻译:
实现二叉查找树的迭代器。你实现的迭代器会使用二叉查找树的根节点来初始化。 调用next()方法会返回二叉搜索树里下一个最小的数。 注意:next()和hasNext()方法的时间和空间复杂度要求分别是O(1)和O(h),其中h是树的高度。 解题思路:
二叉查找树的性质是,每个节点的左节点小于它,而右节点大于它。最小的节点总是存在于树的最左侧,直接遍历获取的时间复杂度是O(h),而空间复杂度是O(1)。 题目中要求实现O(1)的时间复杂度和O(h)的空间复杂度。注意到每次获取最左侧的节点时,我们总会重复访问从根节点开始的所有左节点。因此我们可以用栈来存储遍历时经过的节点。 初始化的时候,把从根节点开始的所有左节点压入栈中,此时栈顶元素是最左下方的节点,亦即当前的最小值。next()函数弹出并返回栈顶元素。然后将弹出的节点的右子树的左侧节点依次压入栈中。这个操作和初始化时的压栈操作是相同的,故将其单独提取为一个函数。使用了栈以后,hasNext()函数只需返回栈是否为空即可。若栈不为空,那么尚有最小的元素未被访问,否则整棵树都已经被访问过。 时间和空间复杂度:
如题目要求,时间复杂度是O(1), 空间复杂度是O(h)。 代码如下: 1. / 2. * Definition for binary tree 3. * struct TreeNode { 4. * int val; 5. * TreeNode left; 6. * TreeNode right; 7. * TreeNode(int x) : val(x), left(NULL), right(NULL) {} 8. * }; 9. / 10. class BSTIterator { 11. public: 12. BSTIterator(TreeNode root) { 13. pushStack(root); 14. } 15. 16. / @return whether we have a next smallest number / 17. bool hasNext() { 18. return !st.empty(); 19. } 20. 21. / @return the next smallest number / 22. int next() { 23. TreeNode node = st.top(); 24. st.pop(); 25. pushStack(node->right); 26. return node->val; 27. } 28. private: 29. stack st; 30. void pushStack(TreeNode node) { 31. while (node != nullptr) { 32. st.push(node); 33. node = node->left; 34. } 35. } 36. }; 37. 38. /* 39. * Your BSTIterator will be called like this: 40. * BSTIterator i = BSTIterator(root); 41. * while (i.hasNext()) cout << i.next(); 42. /