Building a Binary Search Tree
For this activity, you will need to be using an Integrated Development Environment (IDE). The recommended IDE for this module is JetBrains IntelliJ IDEA for Python and JetBrains CLion for C++. You can follow instructions at the following page to set up your development environment:
Setting up your Development Environment
Task 1 - Implementing the Node Class
For this task you need to implement a node
class and will be used to store pointers to the relevant child nodes
for that parent node. The node itself should also hold the value (or data) that is associated with the parent node.
This can be either a numeric or string value.
Task 2 - inserting a Node into the Tree
For this task you need to implement a function that will enable the user to insert a new node into the BST. When the node is inserted, it should be appended as a leaf node in the correct spot.
In the example below, the user is concerned with inserting the value 7
into the binary search tree. The function should traverse through
the BST and find the suitable location to append the new node. In this instance, it would be on the right hand-side
of parent node 6
.
Before Insertion
After Insertion
Task 3 - Searching the Tree
For this task, you are required from the pseudocode given below to create two search methods for a Binary Search Tree (BST), one iterative and the other recursive.
The iterative method will be called find_i()
, whilst the recursive method will be called find_r()
. The find_r()
method will need a sub_method called _find_r()
. Each of these methods should return True
, False
or None
.
Note, that the solution for None
is not given in the iterative pseudocode.
Pseudocode: Iterative Search
FIND_I(tree, target)
cur_node ← tree.root
WHILE cur_node != 0
IF cur_node.value = target
RETURN cur_node (or TRUE)(or cur_node.value)
ELSE IF cur_node.value > target
cur_node ← cur_node.left
ELSE
cur_node ← cur_node.right
RETURN FALSE
Pseudocode: Recursive Search
FIND_R(tree, target)
IF tree.root
IF tree._FIND_R(target, tree.root)
RETURN True
RETURN False
ELSE
RETURN None
_FIND_R(target, cur_node)
IF target > cur_node.data AND cur_node.right
RETURN tree._FIND_R(target, cur_node.right)
ELSE IF target < cur_node.data AND cur_node.left
RETURN tree._FIND_R(target, cur_node.left)
IF target == cur_node.data
RETURN True
Task 4 - Deleting a Node
For this task you are required to implement an iterative method called remove which deletes a node and reorganises the tree using the pseudocode provided below. There a hints included where the pseudocode is missing.
Implement your solution and ensure that the remove method works correctly, i.e. not only is the node deleted, but the tree is also correctly re-organised. Add comments to your code to show your understanding.
Pseudocode: Removing a Node
REMOVE(tree, target)
IF tree.root IS None
RETURN False
ELSE IF tree.root.data = target
IF tree.root.left IS None AND tree.root.right IS None
tree.root ← None
ELSE IF tree.root.left AND tree.root.right IS None
tree.root ← tree.root.left
ELSE IF tree.root.left IS None AND tree.root.right
tree.root ← tree.root.right
ELSE IF tree.root.left AND tree.root.right
delNodeParent ← tree.root
delNode ← tree.root.right
WHILE delNode.left
delNodeParent ← delNode
delNode = delNode.left
tree.root.data ← delNode.data
IF delNode.right
IF delNodeParent.data > delNode.data
delNodeParent.left ← delNode.right
ELSE IF delNodeParent.data < delNode.data
delNodeParent.right ← delNode.right
ELSE
IF delNode.data < delNodeParent.data
delNodeParent.left ← None
ELSE
delNodeParent.right ← None
parent ← None
node ← tree.root
WHILE node and node.data != target
parent ← node
IF target < node.data
node ← node.left
ELSE IF target > node.data
node ← node.right
IF node IS None OR node.data != target //CASE 1: Target not found
RETURN False
ELSE IF node.left IS None AND node.right IS None //CASE 2: Target has no children
IF target < parent.data
parent.left ← None
ELSE
parent.right ← None
RETURN True
ELSE IF node.left AND node.right IS None //CASE 3: Target has left child only
IF target < parent.data
parent.left ← node.left
ELSE
parent.right ← node.left
RETURN True
// NOT IMPLEMENTED //CASE 4: Target has right child only
ELSE //CASE 5: Target has left and right children
delNodeParent ← node
delNode = node.right
WHILE delNode.left
delNodeParent ← delNode
delNode ← delNode.left
node.data ← delNode.data
IF delNode.right
IF delNodeParent.data > delNode.data
delNodeParent.left ← delNode.right
ELSE IF delNodeParent < delNode.data
delNodeParent.right ← delNode.right
ELSE
IF delNode.data < delNodeParent.data
delNodeParent.left ← None
ELSE
delNodeParent.right ← None
Task 5: Visualising a Tree
For this task you will implement a function that will display the BST in the terminal window. You may want to consider printing the tree in a method that looks like the following:
1
/ \
2 3
/ \ / \
4 5 6 7
Struggling?
If you are struggling with this lab activity, you may want to get some additional support. You can speak to the module leader/team in the room of when the lab week is active, or you can visit the Additional Support page for more information on how you can get extra support.