






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
Material Type: Exam; Professor: Earls; Class: Data Structures; Subject: Computer Science; University: University of Illinois - Urbana-Champaign; Term: Summer 2005;
Typology: Exams
1 / 12
This page cannot be seen from the preview
Don't miss anything!







3:00pm – 4:15pm Wednesday, July 27
You are given the AVLTreeNode class shown on page 8 of the exam. You want to write a function doubleRight that has one parameter and returns nothing. The parameter will be of type reference-to-pointer-to-AVLTreeNode. You can assume this parameter points to the root of a subtree for which it is possible to perform a double right rotation. The function should perform that rotation – including fixing the heights of whatever nodes will need their heights fixed. You can assume all heights in all nodes, are correct prior to the double rotation operation.
void doubleRight(AVLTreeNode * & ptr) { // your code goes here
TreeNode* firstRot = ptr->left;
TreeNode* temp = firstRot->right; firstRot->right = temp->left; temp->left = firstRot; firstRot = temp; // fix height
ptr->left = temp->right; temp->right = ptr; ptr = temp; // fix height
You have the DSNode class shown on page 8 of the exam, as well as the Array class shown on page 9 of the exam. You want to write a function makeTrees, which has one parameter, an Array
Array<DSNode*> makeTrees(Array
Array<DSNode*> dynamicSets(1, sets.size()); for (int i = 1; i <= dynamicSets.size(); i++) dynamicSets[i] = new DSNode(i);
for (int i = 1; i <= sets.size(); i++) dynamicSets[i].parent = dynamicSets[sets[i]];
return dynamicSets; }
You want to write a method countLeftFirst that has one parameter, an Array
int countLeftFirst(Array
int total = 0; for (int i = 1; i <= tree.size()/2; i++) if ((tree[2 * i] < tree[i]) && (tree[2 * i] < tree[2 * i + 1])) total++;
return total; }
(b) You have three values in a red-black tree – a root with two children, with the two children being red. What is the maxium number of rotations that the next insertion could result in? Justify your answer.
You will not have any rotations. Your next insertion has to be a leaf, so it has to be a child of one of the root’s two children. A new node could not possibly go anywhere else, according to the BST insert algorithm. No matter which of the root’s two children is the parent of our new node, our new node will be red, and it’s parent and sibling will both be red. So this is the “red uncle” case of the insert algorithm; we solve this by coloring the new node’s parent and parent’s sibling black, the grandparent red, and relabelling the grandparent as ”x”. So now we have a red root with two black children, one of which has a red leaf as a child. The last thing we do is “leave the loop” and color the root black again...and then we are done. So no rotations are needed at all.
You want to create a two-dimensional sparse array. That is, you want an interface that lets you pass in a “row” index and “column” index and, using those indices, gives you the unique value associated with that pair of indices. However, behind the scenes, we will not necessarily implement this with a two-dimensional array. Specifically, we are deciding between two possible implementations. One of our options is a linked list whose nodes each hold a row index and an array of integers. In this case, to look up a value, we first search the linked list for the desired row, and then, given the array at that linked list node, use our column index as the array index we want – the value in that cell is what we are looking for. The second option is a red-black tree whose nodes each hold a row index and an AVL tree. Searching the red-black tree for the row index will give us the relevant AVL tree. The AVL tree will hold two indices in each node – a column index and the value associated with that column for the given row we looked up in the red-black tree. So to obtain our value, we then search the AVL tree for the column index. If our goal is to have the fastest worst-case time we can for obtaining a value, given the value’s row and colum, then which of these two implementations is preferable? Justify your answer convincingly. You can assume any running time we have stated in class about linked lists, arrays, red-black trees, or AVL trees.
THE ANSWER: For our first option, array lookup is done by searching the linked list for a row value (this would be O(n)) and then once we find it, access the array there to get the column we want (which would be O(1)). So, we have O(n) + O(1) = O(n). Our second option is to search a red-black tree for a row value (this would be O(log n)) and then once we find it, access the AVL tree there and search it to get the column we want (this would also be O(log n)). So we have O(log n) + O(log n) = O(log n). So the second way is the better of the two, since in order to find the value you need to acces both structures, and that total time will be better in the second implementation.
template
// Here are the member function declarations for the Array class; // we’ve left the declarations for the variables, iterators and iterator // support functions (begin(), end(), etc.) out; you don’t need them. Array(); // size 0 array, indiced 0 through - Array(int low, int high); // indices low through high Array(Array
Etype & operator[](int index); // accesses cell at param index void initialize(Etype const & initElement); // inits all cells to param void setBounds(int theLow, int theHigh); // changes bounds of array, int size() const; // returns number of cells in array int lower() const; // returns lowest index int upper() const; // returns upper index };
(scratch paper, page 1)