Implement Binary Search Tree(BST) Iterator
Last Updated :
15 Nov, 2023
Binary Search Trees (BSTs) are data structures, in computer science. They are commonly used for searching, insertion and deletion operations. In situations it becomes necessary to traverse a BST in an order. For example an in order traversal visits nodes in ascending order based on their values. This article explores the creation of a BSTIterator class that facilitates the in order traversal of a search tree.
In this article, we will implement the BSTIterator class that represents an iterator over the in-order traversal of a binary search tree (BST):
- BSTIterator(TreeNode root): Initializes an object of the BSTIterator class. The root of the BST is given as part of the constructor. The pointer should be initialized to a non-existent number smaller than any element in the BST.
- boolean hasNext(): Returns true if there exists a number in the traversal to the right of the pointer, otherwise returns false.
- int next(): Moves the pointer to the right, then returns the number at the pointer.
Notice that by initializing the pointer to a non-existent smallest number, the first call to the next() will return the smallest element in the BST. You may assume that the next() calls will always be valid. That is, there will be at least a next number in the in-order traversal when the next() is called.
Note: Time complexity for next, hasNext – O(1) and Space Complexity – O(N)
Approach and Implementation:
To achieve this functionality efficiently we can utilize a stack to keep track of the nodes along the path of the in-order traversal. Here is an explanation of how we can implement the BSTIterator class step by step;
1. Constructor (BSTIterator(TreeNode root)):
In the constructor we initialize the stack. Populate it with nodes from the leftmost path of the BST. This ensures that initially, the stack contains the elements of the tree.
Java
public BSTIterator(TreeNode root) {
stack = new Stack<>();
pushAllLeft(root);
}
|
The pushAllLeft function is a helper function that pushes all nodes from the node to its leftmost child onto the stack.
2. Boolean hasNext():
This method checks whether there are elements to traverse. It returns true if there are still elements remaining in the, in order traversal.
Java
public boolean hasNext() {
return !stack.isEmpty();
}
|
3. Int next():
The next() function is responsible, for advancing the pointer to the following element during an in order traversal and returning that element. This is accomplished by removing the node from the stack and subsequently adding all the children of the right subtree of that node back, onto the stack.
Java
public int next() {
TreeNode node = stack.pop();
if (node.right != null ) {
pushAllLeft(node.right);
}
return node.val;
}
|
To guarantee that all left children of the subtree are included we also utilize the pushAllLeft function in this scenario.
Example:
Input: 7
/ \
3 15
/ \
9 20
Output: 3, 7, 9, 15, 20.
Below is the implementation of the BST Iterator:
C++
#include <iostream>
#include <stack>
using namespace std;
class TreeNode {
public :
int val;
TreeNode* left;
TreeNode* right;
TreeNode( int val) : val(val), left(nullptr), right(nullptr) {}
};
class BSTIterator {
private :
stack<TreeNode*> st;
void pushAllLeft(TreeNode* node) {
while (node != nullptr) {
st.push(node);
node = node->left;
}
}
public :
BSTIterator(TreeNode* root) {
pushAllLeft(root);
}
bool hasNext() {
return !st.empty();
}
int next() {
TreeNode* node = st.top();
st.pop();
if (node->right != nullptr) {
pushAllLeft(node->right);
}
return node->val;
}
};
int main() {
TreeNode* root = new TreeNode(7);
root->left = new TreeNode(3);
root->right = new TreeNode(15);
root->right->left = new TreeNode(9);
root->right->right = new TreeNode(20);
BSTIterator iterator(root);
while (iterator.hasNext()) {
cout << iterator.next() << endl;
}
cout << endl;
return 0;
}
|
Java
import java.util.Stack;
class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode( int val) { this .val = val; }
}
class BSTIterator {
private Stack<TreeNode> stack;
public BSTIterator(TreeNode root)
{
stack = new Stack<>();
pushAllLeft(root);
}
public boolean hasNext() { return !stack.isEmpty(); }
public int next()
{
TreeNode node = stack.pop();
if (node.right != null ) {
pushAllLeft(node.right);
}
return node.val;
}
private void pushAllLeft(TreeNode node)
{
while (node != null ) {
stack.push(node);
node = node.left;
}
}
public static void main(String[] args)
{
TreeNode root = new TreeNode( 7 );
root.left = new TreeNode( 3 );
root.right = new TreeNode( 15 );
root.right.left = new TreeNode( 9 );
root.right.right = new TreeNode( 20 );
BSTIterator iterator = new BSTIterator(root);
while (iterator.hasNext()) {
System.out.println(iterator.next());
}
}
}
|
Python3
class TreeNode:
def __init__( self , val):
self .val = val
self .left = None
self .right = None
class BSTIterator:
def __init__( self , root):
self .st = []
self .pushAllLeft(root)
def pushAllLeft( self , node):
while node:
self .st.append(node)
node = node.left
def hasNext( self ):
return len ( self .st) > 0
def next ( self ):
node = self .st.pop()
if node.right:
self .pushAllLeft(node.right)
return node.val
root = TreeNode( 7 )
root.left = TreeNode( 3 )
root.right = TreeNode( 15 )
root.right.left = TreeNode( 9 )
root.right.right = TreeNode( 20 )
iterator = BSTIterator(root)
while iterator.hasNext():
print (iterator. next ())
|
C#
using System;
using System.Collections.Generic;
public class TreeNode
{
public int val;
public TreeNode left;
public TreeNode right;
public TreeNode( int val)
{
this .val = val;
}
}
public class BSTIterator
{
private Stack<TreeNode> stack;
public BSTIterator(TreeNode root)
{
stack = new Stack<TreeNode>();
PushAllLeft(root);
}
public bool HasNext()
{
return stack.Count > 0;
}
public int Next()
{
TreeNode node = stack.Pop();
if (node.right != null )
{
PushAllLeft(node.right);
}
return node.val;
}
private void PushAllLeft(TreeNode node)
{
while (node != null )
{
stack.Push(node);
node = node.left;
}
}
public static void Main( string [] args)
{
TreeNode root = new TreeNode(7);
root.left = new TreeNode(3);
root.right = new TreeNode(15);
root.right.left = new TreeNode(9);
root.right.right = new TreeNode(20);
BSTIterator iterator = new BSTIterator(root);
while (iterator.HasNext())
{
Console.WriteLine(iterator.Next());
}
}
}
|
Javascript
class TreeNode {
constructor(val) {
this .val = val;
this .left = null ;
this .right = null ;
}
}
class BSTIterator {
constructor(root) {
this .stack = [];
this .pushAllLeft(root);
}
pushAllLeft(node) {
while (node !== null ) {
this .stack.push(node);
node = node.left;
}
}
hasNext() {
return this .stack.length > 0;
}
next() {
const node = this .stack.pop();
if (node.right !== null ) {
this .pushAllLeft(node.right);
}
return node.val;
}
}
const root = new TreeNode(7);
root.left = new TreeNode(3);
root.right = new TreeNode(15);
root.right.left = new TreeNode(9);
root.right.right = new TreeNode(20);
const iterator = new BSTIterator(root);
while (iterator.hasNext()) {
console.log(iterator.next());
}
|
Time Complexity: O(N)
Auxiliary Space: O(N)
Share your thoughts in the comments
Please Login to comment...