PROGRAMMING II – ABSTRACT DATA TYPES Unassessed Coursework 4: Binary Search Trees, Heaps and Hash Tables The aims of this coursework is to practice: using Binary Search Trees (BST), by writing examples of high-level procedures and using them in small problems. using heaps and hash tables, by writing examples of access procedures, high-level procedures and small problem applications. 1. Assume the Java type declaration for the dynamic implementation of a BST given in Slide 3 of the lecture nodes on BST, with searchkey of type Integer and value of type String. Give the Java implementation of the following access procedure using recursion: public String retrieve(int searchKey) //post: Returns the item in the BST whose search key equals searchKey. //Returns null if no such item exists 2. Assume the availability of an ADT List of integers, with access procedures isEmpty, add, remove, get, and the availability of an ADT BinarySearchTree<String Integer> with its own access procedures, including the access procedures getLeftSubTree and getRightSubTree. Write the Java implementation of the following high-level procedures, using recursion: public List TreetoList(BinarySearchTree<String, Integer> myTree). //post: Returns a list containing the item values in the tree in descending //order. public List getOdd(BinarySearchTree<String, Integer> myTree) //post: Returns a list containing the odd (i.e. not divisible by 2) values in //the tree in ascending order. 3. The following Abstract Data Type QueueTrees consists of a queue of Binary Search Trees. The queue’s node includes a value of type char, and the tree’s node includes a search key of type Integer and a value of type String as illustrated in the picture below. QueueTrees last first 5 A B . . T 2 Name Name 11 10 Name 7 Name 20 Name Name (a) Give the Java type declarations for this ADT QueueTrees including the type declarations of all the data structures needed to implement it. (b) Assume now the existence of a class BinarySearchTree that implements an ADT BinarySearchTree. Give the new type declaration for QueueTrees. (c) Using your answer to part (b), give the Java implementation of the following access procedure. Include all additional access procedures needed to implement this access procedure. public void AddNewTNode(Integer searchKey, String newName){ //pre: Takes newName and a key value searchKey. //post: insert a new node with the given name and search key in the tree //referenced by the first node in the queue. 4. Consider the static implementation of an ADT Heap illustrated diagrammatically in slide 6 of the lecture notes on Heaps. Assume the elements included in the heap to be of type Integer. (a) Give the Java data structure declaration for such type of implementation, assuming the maximum size of the heap to be equal to 100. (b)Implement the constructor for creating an empty heap, and the access procedures isEmpty( ) and heapInsert(Integer newItem). Provide also an appropriate HeapException method. 5. In slide 9 of the lecture notes on Heaps, I gave the pseudocode of the procedure heapRebuild. Assume now this procedure to be an auxiliary procedure of a class Heap that implements a heap. Using the Java data structure declaration you have given in question 4(a), give the Java implementation of auxiliary procedure heapRebuild, declared as follows: protected void heapRebuild(Integer[ ] items, int root, size) //pre “root” is the index of the semi-heap’s root that has to be placed at //the proper position. 6. Assume the existence of a class Heap that implements an ADT heap of elements of type T. Implement an ADT PriorityQueue, of elements also of type T, that uses the class Heap as underlying data structure, and has the access procedures defined by the following interface. For simplicity, ignore the cases of exception. public interface PQInterface<T>{ public boolean pqisEmpty(); //pre: none //post: Insert newItem in the priority queue at its proper position. public void pqInsert(T newItem) //pre: none //post: Retrieve and delete the item with highest priority. public T pqDelete( ) } 7. Assume the existence of a class Heap that implements an ADT heap of elements of type Integer. Give the Java implementation of the following high-level procedure. If you use any auxiliary procedure, give also its implementation. public Heap ChangeItem(Heap myHeap, Integer Item, newItem) //pre: myHeap is not empty //post: returns a new heap equal to myHeap but with Item replaced by //newItem, if Item is in myHeap. 8. Assume an hash table of just integers, that uses the hash function h(x) = x mod 7 and a separate chaining strategy for resolving conflicts. What does the hash table loop like after the following insertions occur? 8, 10, 24, 15, 32, 17 9. Consider the following two hash functions: h1(key) = key div 250 h2(key) = key mod 250 where the possible key range is the set of integers 1, 2, 3,…, 1000. Assume the hash table to be an array of size 250, where each item is capable of holding 2 items, and to use an open addressing scheme to resolve collisions. For each of the functions h1 and h2, show the distribution of the keys among the table after the following insertions are performed: (a) 1,2,3,…,250 are added to an empty table (b) 5, 10, 15, 20, …, 980, 985, 990, 995, 1000 are added to an empty table. (c) What conclusion can you draw from this example about the selection of a hash function?