



Study with the several resources on Docsity
Earn points by helping other students or get them with a premium plan
Prepare for your exams
Study with the several resources on Docsity
Earn points to download
Earn points by helping other students or get them with a premium plan
An explanation of binary search trees, their properties, and the implementation of basic operations such as insertion, removal, and traversal. Students are encouraged to read related chapters and lessons to gain a better understanding of the concepts. Pseudo-code for the add and remove functions, as well as an invitation to try executing these functions on the given binary search tree.
Typology: Exams
1 / 5
This page cannot be seen from the preview
Don't miss anything!




In Preparation : Read Chapter 8 to learn more about the Bag data type, and chapter 10 to learn more about the basic features of trees. If you have not done so already, read Lessons 21 and 22 for alternative implementation of the Bag. In this worksheet we will start to explore how to make a useful container class using the idea of a binary tree. A binary search tree is a binary tree that has the following additional property: for each node, the values in all descendants to the left of the node are less than or equal to the value of the node, and the values in all descendants to the right are greater than or equal. The following is an example binary search tree: Notice that an inorder traversal of a BST will list the elements in sorted order. The most important feature of a binary search tree is that operations can be performed by walking the tree from the top (the root) to the bottom (the leaf). This means that a BST can be used to produce a fast Bag implementation. For example, suppose you find out if the name “Agnes” is found in the tree shown. You simply compare the value to the root (Alex). Since Agnes comes before Alex, you travel down the left child. Next you compare “Agnes” to “Abner”. Since it is larger, you travel down the right. Finally you find a node that matches the value you are searching, and so you know it is in the collection. If you find a null pointer along the path, as you would if you were searching for “Sam”, you would know the value was not in the collection. Adding a value to a binary search tree is easy. You simply perform the same type of traversal as described above, and when you find a null value you insert a new node. Try inserting the values “Amelia”. Then try inserting “Sam”.
Insertion is most easily accomplished by writing a private internal function that takes a Node and a value, and returns the new tree in which the Node has been inserted. In pseudo-code this routine is similar to the following: Node add (Node start, E newValue) if start is null then return a new Node with newValue otherwise if newValue is less than the value at start then set the left child to be the value returned by add(leftChild, newValue) otherwise set the right child to be add(rightChild, newValue) return the current node Removal is the most complex of the basic Bag operations. The difficulty is that removing a node leaves a “hole”. Imagine, for example, removing the value “Alex” from the tree shown. What value should be used in place of the removed element? The answer is the leftmost child of the right node. This is because it is this value that is the smallest element in the right subtree. The leftmost child of a node is the value found by running through left child Nodes as far as possible. The leftmost child of the original tree shown above is “Abigail”. The leftmost child of the right child of the node “Alex” is the node “Alice”. It is a simple matter to write a routine to find the value of the leftmost child of a node. You should verify that in each case if you remove an element the value of the node can be replaced by the leftmost child of the right node without destroying the BST property. A companion routine (removeLeftmost) is a function to return a tree with the leftmost child removed. Again, traverse the tree until the leftmost child is found. When found, return the right child (which could possibly be null). Otherwise as you return through the Nodes set the left child to the value returned by the recursive call, and return the current Node. Armed with these two routines, the general remove operation can be described as follows. Again it makes sense to write it as a recursive routine that returns the new tree with the value removed. Node remove (Node start, E testValue) if start.value is the value we seek decrease the value of dataSize if right child is null return left child otherwise replace value of node with leftmost child of right child set right child to be removeLeftmost(right child) otherwise if testValue is smaller than start.value set left child to remove (left child, testValue) otherwise set right child to remove (right child, testValue) return current node
struct node * removeLeftmostChild (struct node *current) { } void BSTnodeRemove (struct node * current, EleType d) { }