0% found this document useful (0 votes)
62 views

Binary Search Tree

The document discusses binary search trees, including their pre-order, in-order, and post-order traversal algorithms. It provides Java code for implementing a binary search tree with methods for insertion, searching, and the different traversal types. The time and space complexity of operations on a binary search tree are analyzed. Potential applications including sorting a dynamic data set using in-order traversal are described, along with advantages and disadvantages of binary search trees.

Uploaded by

viswanath kani
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
62 views

Binary Search Tree

The document discusses binary search trees, including their pre-order, in-order, and post-order traversal algorithms. It provides Java code for implementing a binary search tree with methods for insertion, searching, and the different traversal types. The time and space complexity of operations on a binary search tree are analyzed. Potential applications including sorting a dynamic data set using in-order traversal are described, along with advantages and disadvantages of binary search trees.

Uploaded by

viswanath kani
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 6

Binary search tree

Pre-Order Traversal

The traversals of a Binary Search Tree are similar to that of any Binary Tree.

Below is the algorithm for the pre-order traversal of a Binary Search Tree.

1. if node == null, do nothing. else, do steps 2, 3, 4.


2. print the current node.
3. Visit the left subtree and repeat step 1.
4. Visit the right subtree and repeat step 1.

If the node is null, we don’t do anything.

If it is non-null, we first visit the current node, then the left subtree and then the right subtree.

In-Order Traversal

Below is the algorithm for the in-order traversal of a Binary Search Tree.

1. if node == null, do nothing. else, do steps 2, 3, 4.


2. Visit the left subtree and repeat step 1.
3. print the current node.
4. Visit the right subtree and repeat step 1.

If the node is null, we don’t do anything.

If it is non-null, we first visit the left subtree, then the current node and then the right subtree.

Post-Order Traversal

Below is the algorithm for the post-order traversal of a Binary Search Tree.

1. if node == null, do nothing. else, do steps 2, 3, 4.


2. Visit the left subtree and repeat step 1.
3. Visit the right subtree and repeat step 1.
4. print the current node. If the node is null, we don’t do anything.

If it is non-null, we first visit the left subtree, then the right subtree and then the current node.

Implementation of Binary Search Trees


Binary Search Tree in Java

class Node {
int key;
Node left;
Node right;
public Node(int key) {
this.key = key;
}
}

class `BST` {
private Node root;

public void insert(int key) {


root = insert(root, key);
}

private Node insert(Node node, int key) {


if (node == null) {
return new Node(key);
}
if (key <= node.key) {
node.left = insert(node.left, key);
} else {
node.right = insert(node.right, key);
}
return node;
}

public Node search(int key) {


return search(root, key);
}

private Node search(Node node, int key) {


if (node == null || node.key == key) {
return node;
}
if (key <= node.key) {
return search(node.left, key);
}
return search(node.right, key);
}

public void inOrder() {


System.out.print("The inOrder traversal is: ");
inOrder(root);
System.out.println();
}

private void inOrder(Node node) {


if (node == null) {
return;
}
inOrder(node.left);
System.out.print(node.key + " ");
inOrder(node.right);
}

public void preOrder() {


System.out.print("The preOrder traversal is: ");
preOrder(root);
System.out.println();
}

private void preOrder(Node node) {


if (node == null) {
return;
}
System.out.print(node.key + " ");
preOrder(node.left);
preOrder(node.right);
}

public void postOrder() {


System.out.print("The postOrder traversal is: ");
postOrder(root);
System.out.println();
}

private void postOrder(Node node) {


if (node == null) {
return;
}
postOrder(node.left);
postOrder(node.right);
System.out.print(node.key + " ");
}
}

public class BinarySearchTree {


public static void main(String[] args) {
`BST` `bst` = new `BST`();
`bst`.insert(10);
`bst`.insert(15);
`bst`.insert(5);
`bst`.insert(8);
`bst`.insert(18);
`bst`.insert(12);
`bst`.insert(10);

`bst`.preOrder();
`bst`.inOrder();
`bst`.postOrder();

search(`bst`, 12);
search(`bst`, 9);
}

private static void search(`BST` `bst`, int key) {


if (`bst`.search(key) != null) {
System.out.println(key + " found");
} else {
System.out.println(key + " not found");
}
}
}

Output:
The preOrder traversal is: 10 5 8 10 15 12 18
The inOrder traversal is: 5 8 10 10 12 15 18
The postOrder traversal is: 10 8 5 12 18 15 10
12 found
9 not found
Time Complexity of Binary Search Tree

Insert/Search

Since in any insert/search operation, we start from the top (root) and traverse until the end of
a leaf node of the tree, we can say that on average, the time complexity will depend on the
height of our Binary Search Tree.

If the elements are inserted in such a way that the left or the right subtree becomes much
heavier (skewed) than the other, then the time complexity might vary depending on the
element to be inserted.

For instance, if the elements are inserted in a sorted increasing order, then the elements will
always be inserted in the right subtree. This will orient the tree in the right direction, making
it skewed.

The height of the tree in the above case will be almost O(N) where N is the total number of
elements in the tree. Hence, in the worst case, it will take O(N) time for each insert/search
operation on average.

On the other hand, if the elements are inserted randomly, the tree will be much more balanced
on both sides. The height of the tree in this case will be
approximately �(���2�)O(log2N) and hence the time complexity for each
insert/search operation on average will be �(���2�)O(log2N) as well.

Traversals

For the traversals, we have to visit all the nodes of the tree. It doesn’t matter the order in
which we visit them. We end up visiting all of them.

Hence, the time complexity will always be O(N).

Space Complexity of Binary Search Tree

Insert/Search

In insert operation, we always end up creating a new node in the end. But in the search
operation, we never create any new nodes. But in any case, the memory requirement is still
constant, i.e. O(1) in both of them.

If you think about it, the space complexity actually depends on the implementation used. If
we use a recursive approach, we use the recursion stack to store the recursive function calls.

While for an iterative approach, we don’t use the recursive stack, rather just a single variable
to store the current node.

If you choose to ignore the memory used by the recursion stack, the space complexity
remains constant, i.e. O(1) irrespective of the approach used for both insert and search
operations.
Hence, the total space complexity required for N insertions will be O(N).

Traversals

This space complexity of all the traversals can be thought of in a similar way.

Since we don’t use any extra memory other than the recursion stack, the space complexity is
constant, i.e. O(1) for all the traversals.

Food for thought: In the examples above, our data set consisted of integers only. If our data
set consists of strings only, what do you think the time and space complexity will be in that

case? 😛

Applications of Binary Search Trees


Binary Search Tree works really well if your data set is dynamic and constantly updated, i.e.
there are a lot of insertions or deletions.

The only drawback one can think of is if the elements are inserted in a particular order which
imbalances the tree and makes it skewed in one direction, then the cost of insertions and
search will increase like we discussed before.

Food for thought: There are a couple of improvements on the traditional Binary Search
Tree implementation wherein the tree is always balanced. Thus, it doesn’t matter if the
elements are inserted in a sorted order or not, the tree will automatically balance itself in
order to balance its height, which will always be �(���2�)O(log2N).

Binary Search Trees can also be used to sort a dynamic data set. Did you notice the output of
the in-order traversal above? That’s right. The in-order traversal always gives the sorted
increasing order of all the elements.

Thus, if the data set is dynamic, i.e. elements are getting inserted and deleted, and we need to
find the sorted order of the elements at any point of time, we can just use the in-order

traversal of the Binary Search Tree. Neat right? 😛

Advantages of Binary Search Trees


1. Unlike Binary Search, which works only for a fixed data set, Binary Search Trees can be used
for dynamic data sets as well.
2. It can be used to find the sorted order of a dynamic data set.
3. If elements are inserted/deleted randomly, it is actually faster to do it in a binary search
tree than in linked lists and arrays.
4. We can actually calculate a lot more stuff using a Binary Search Tree like the floor and ceiling
values for any element.

Disadvantages of Binary Search Trees


1. The overall shape of the tree depends on the order of insertion. If data is inserted in a sorted
order or the tree becomes heavier(skewed) in one direction, the insert/search operations
become expensive.
2. A lot of space is required as we need to store the left and right child of each node.
3. The plain implementation of Binary Search Tree is not much used since it cannot guarantee
logarithmic complexity. Hence, we have to use self balancing implementations which are a
bit more complex to understand and implement.

You might also like