Java Program to Implement Binary Search Tree
5 stars based on
Click on HC to toggle high contrast mode. When you move your mouse over some bold words in high contrast mode, related words are automatically highlighted.
Text is shown in black and white. A Binary Search Tree is a recursive data structure central to computer science. In earlier lessons we saw how Linked Lists provide dynamic behavior that improves on contiguous arrays. However, Linked Lists only provide O n behavior for determining whether an element is in the list. Given an array of sorted search results for binary tree java code, you can use Binary Array Search to determine efficiently whether the array contains a given item in O log n time.
This code shows how to implement the algorithm:. In the binary package, create a BinaryArraySearch class as shown:. Because 7 does not appear in the array, you can use search results for binary tree java code return value from binarySearch to determine where in the array 7 could be inserted to maintain the sorted order. When the return value is less than zero, negate it and subtract 1 to find the correct location to store the value in A.
In this case, 7 should be inserted at index location 2, which would place it between 5 and 8 as it should be. The second line of output shows that the search is able to locate element 2 at index location 0. Arrays are unable to delete and insert items efficiently while maintaining a specific ordering of elements.
However, Linked Lists can insert elements anywhere in the collection, but then searching for a given item wil require O n time. Binary Search Trees offer the impressive ability to maintain items in a structured order and on average, it can support adding, removing, and searching for items in O log n time.
In this lesson, you will construct a Binary Search Tree implementation from scratch. Through various performance code you'll see that the naive implementation can lead to worst-case performance of O n for all key operations. At the end of the lesson, you'll learn how to "balance" the tree to improve the average case performance.
A Binary Search Tree is a finite set of nodes where each node stores a typed value known as the key for the node. This property is known as the binary search tree property. If subtrees left and right are null, the node is called a leaf node.
There can be two or more nodes in the search tree with the same key value, but if you want to restrict the tree to conform to Set-based semantics as defined in search results for binary tree java code Java Collections Framework while ensuring that the same implementation will work, you need to prevent the insertion of duplicate keys.
For this lesson, assume that duplicate keys may exist in the BST. BinaryNode is a generic class with the parameter, Ethat determines the type of the key attribute. The only restriction is that the type of the key must implement Comparableotherwise there will be no way to order the key values. BinaryNode defines left and right attributes to refer to the left and right subtrees, respectively.
The size method counts the nodes in a BST rooted at a given node. Because a BST is a recursive data structure, the implementation of size is also recursive. Throughout this lesson, you see how to apply recursion to implement the required BST operations.
The size n 'll helper method allows size to be written in its simplest form. So, the size of a BST rooted at a given node n is 1 plus the respective sizes of the left and right subtrees or n.
Add these methods to the end of the BinaryNode class:. The binary search tree property states that all keys in the left subtree of a node are less than or equal to the node's key, and all keys in the right subtree of a node are greater than the node's key.
For this discussion, assume that add k is invoked on node n where k is less than or equal to n 's key. There are two cases to consider:. If there is no left subtree then a new node containing this key is created to be the left subtree of n.
This is the case in add parent,k when parent is null. If, however, the left subtree does exist, then add parent,k requests to add k recursively to that subtree. These two functions present another example of double recursion, where each function calls the other repeatedly until the computation terminates.
Note that the structure of these two methods is similar to the size method presented earlier. In the binary package, create a BinaryTree class as shown:.
The add E k code demonstrates an implementation style necessary for BinaryTree. If root is nullall methods have to handle the special case where the BST is empty. Otherwise, this key is added to the subtree rooted at rootusing the add parent,k method described earlier. Doing so allows the root to be updated as needed. Until you add a contains E k method, there will be no easy way to validate that the above methods work. Add these methods to the end of BinaryTree:.
This method is placed in the BinaryTree class, rather than BinaryNode, because the notion of "containment" is a property of the BST, not an individual node. Also, doing so allows you to avoid constantly checking to find out whether the left or right subtree is empty. Specifically, contains parent,k returns false when parent node is null. This method recursively calls itself on either the left subtree or the right subtree if the node's key doesn't match the target key.
Naturally, once a match is found, true is returned. If you're don't know which to choose, go with JUnit 3. Either is okay, but the resulting file may look slightly different from the one shown here. To determine the efficiency of BinaryTreeyou need to identify the worst case and average case execution of its methods.
You might be able to identify the worst case behavior, that is, when keys are inserted into a BST in increasing sorted order. For example, consider adding the numbers from 1 to 10 into a BST. Each newly inserted key becomes the right-most node in the BST. In fact, the search results for binary tree java code more closely resembles a linked list than a tree because none of the nodes in the BST have a left subtree.
To demonstrate the performance of the add k method in BinaryTreewrite this class:. In search results for binary tree java code binary package, create an Evaluate class as shown:. Let's take a closer look at this code:.
Two arrays of N keys are created; ordered contains the keys in order while shuffled is created by using the Collections. The code conducts trials and records the total time in nanoseconds required to add all keys to the BST.
The code estimates the average cost of adding a random key to the BST by averaging the total time. In addition, the code maintains statistics on the height of the BSTs generated during this process. For the random BSTs, it records the min and max heights of the BSTs and computes the total height so it can report on the average height for n keys. Similar code records statistics for the BST generated from the ordered insertion of keys.
You want to know the average height of the BST because that will determine the performance of the contains method. The minimum height of a BST with n nodes is log n. The average height of the BST created from the shuffled values is about twice the minimum. Also, the average time in nanoseconds to search for all n items grows proportionally with n. For example, when n grows from to a four-fold increase the time to search for all n numbers takes 3. This is much different in the BST constructed from the ordered keys.
The height of the BST is n -1 which means that it's really a linked list. Also, when n grows from toit search results for binary tree java code more than 16 times as search results for binary tree java code to complete all n searches.
Typically you do not have advance warning of the order of the elements being added into the BST, so you need some way to avoid poor performance due to the elements being close to sorted when they were added into the BST. In addition, when the BST degenerates to a Linked List because items are inserted in sorted order the recursive add method can cause a StackOverflowErroras shown above.
The smallest height search results for binary tree java code a tree with n elements is O log nwhich results in a perfectly balanced tree with the left subtree of the root containing roughly the same number of values as the right subtree of the root. This balanced property should apply recursively to all nodes in the tree, not just the root. You could try to rebuild the entire tree after each insertion to make sure that each node is balanced, but that would require way too much work.
Instead, find some incremental strategy that adjusts the structure of the tree only when it becomes unbalanced. In the Collections Framework, the TreeMap class is implemented using Red-Black trees, which are another form of self-balancing binary tree.
After completing this lesson, you'll be able to compare these two approaches to determine which provides the best performance. Let's define the concept of height with AVL nodes. The height of a leaf node is 0 since it has no children. Recursively define the height of an AVL node to be 1 greater than the maximum of the height values of its 2 children nodes if at least 1 exists.
To complete this definition, consider the height of a non-existent child node to be The height difference for a node is defined as height left - height rightthat is, the height of search results for binary tree java code left subtree minus the height of the right subtree. To be as efficient as possible, each AVLBinaryNode stores its computed height in addition to the expected attributes of key search results for binary tree java code, leftand right.
That is, rather than dynamically computing the height of a node when requested, you only perform this computation when a node is added to the AVL tree. Finally, the heightDifference method computes the height difference for a given node, n. This code is nearly identical to its BinaryTree counterpart. The code won't compile until you complete the add method in AVLBinaryNode —be careful with this method. It is possible after just three additions to have the root node of search results for binary tree java code binary tree violate the AVL Property.
Consider an AVL tree with just two nodes, constructed by adding 50 and then To demonstrate that this tree supports the AVL property, you must compare the heights of the children of the root node which stores the value However, there is no right subtree for this node.