







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; Class: Data Structures; Subject: Computer Science; University: University of Illinois - Urbana-Champaign; Term: Unknown 1989;
Typology: Exams
1 / 13
This page cannot be seen from the preview
Don't miss anything!








75 minutes permitted
Print your name, netID, and lab section day/time neatly in the space provided below; print your name at the upper right corner of every page.
Given the following class:
// this would be in the .h file template
Assume that all pointers that are in any way part of the implementation of Map, get set to either NULL or the address of a dynamically object before you call the assignment operator. (Or in other words, assume that when you call the assignment operator, no pointer is pointing to garbage memory.) Write the definition code for the assignment operator (operator=) for the class Map. SOLUTION ON NEXT PAGE
(a) Given the following code, using a singly-linked implementation of the List ADT you saw on MP3, express (using big-O notation) the order of growth of the running time of the code below, in terms of n. Prove your answer is correct (i.e. explain your answer in enough detail to be convincing). (10 points)
List
ANSWER: The running time is O(n^2 ). Inserting each of the n elements will take constant time, and since there are n of those insertions, the first loop is linear time. The call to the Tail() function would either be constant time (if there were a tail pointer as part of the implementation) or else linear time (if there were NOT a tail pointer as part of the implementation and you had to traverse all the way through the list to get to the end). Either way, the running time for the first four lines together is linear time. The second loop will perform a Retrieve() on every node except the first node, starting at the last node and moving backwards. Each Retrieve() is constant time, but the act of moving backwards one position will be linear time, since you need to start at the beginning and traverse to “the node before the current position” in order to move backwards on a singly-linked list. So you are running a linear-time body of the loop n- times, and that is overall quadratic time. (If you want to be more precise, the first time theList--; is run, it will require traversing down n-1 nodes, the second time it is run requires a traversal down n-2 nodes, the third time it is run requires a traversal down n-3 nodes, and so on. And the sum (n-1) + (n-2) + (n-3) + ... + 1 turns out to be a quadratic function of n.) So, since linear plus quadratic is quadratic, the running time is quadratic. (You would not need to be quite so verbose in your own solution.)
(b) Imagine we have the following array-based implemenation of a stack:
class Stack { private: Array
ANSWER: The running time will be O(n). Since there are no additional member vari- ables, you cannot be using a “circular array” to implement this stack. And so the only way to actually get a Pop() operation to work, is to shift all the elements of the stack in the index range 2 through numElements, to the left by one cell, thus moving that range to the index range 1 through numElements-1. Since it takes constant time to shift each value one cell to the left, and we shift n-1 values, the overall running time must be linear. (You would not need to be quite so verbose in your own solution.)
(Move Tens, continued)
void MoveTens(ListNode& head) { // your code goes here ListNode temp = head; Listnode* temp2; ListNode* newHead = NULL; ListNode* newTail = NULL; while (temp != NULL) { temp2 = temp->next; // save value after the current one if ((temp->element >= 10) && (temp->element < 100)) {
// remove node from original list if (temp->prev != NULL) // if there’s a prev node temp->prev->next = temp->next; // prev node should point to next node else // otherwise, this is first node, so head = head->next; // next node is new first node
if (temp->next != NULL) // if there’s a next node temp->next->prev = temp->prev; // next node should point to prev node
// append node to end of new list if (newHead == NULL) { // first node of new list newHead = newTail = temp; newHead->prev = NULL; } else { // not first node of new list newTail->next = temp; temp->prev = newTail; newTail = temp; } } temp = temp2; // now make our "saved value" from before, the current value } if (head != NULL) // if there’s still some of old list left head->prev = newTail; // point first node of old list to last node of new
if (newTail != NULL) { // if there’s anything in the new list newTail->next = head; // last node of new list points to beginning of old, head = newHead; // and the "head" pointer points to start of new } }
(a) You are given the following generic function: template
2 8 3 9 4 0 3 5 7 1 6 *
Write some code that uses iterators for the list theList that we declared above, and the template function above, to print the following line of text. Note that no iterators are declared yet; you will need to do that yourself. (8 points) 8 9 0 5 the end!
list
Imagine you are given a standard Stack class and Queue class, each of which also has a Size() function that tells you how many items are in the data structure, and a no-argument constructor that initializes the data structure to be empty. You want to write a function Thirds which takes as an argument, a reference to a Queue. The function should break the collection of elements inside the queue into three equal-sized pieces (If the number of elements is not a multiple of three, then the piece closest to the front gets an extra value and, if there is an additional extra value, the middle section would get that one.) The Queue should be changed so that the second section of the Queue is reversed, and the first and third sections are swapped. For example, given the following queue:
front rear 10 -2 0 5 7 2 -8 3 4 14 1
you want to change the queue into the following:
front rear 4 14 1 3 -8 2 7 10 -2 0 5
former reversed former third second first section section section
The catch is that we’ve declared a few local integers below for you to use (you don’t have to use all of them, we’ve just given them to you in case you need them), and the only other local variables you can create and use are new Queues and new Stacks.
void Thirds(Queue
(Stack and Queue Interfaces, continued)
void Thirds(Queue
temp1 = param.Size()/3; if (param.Size() % 3 != 0) temp1++; // size of front section temp2 = param.Size()/3; if (param.Size() % 3 == 2) temp2++; // size of middle section
Queue
for (temp3 = 1; temp3 <= temp2; temp3++) reverser.Push(param.Dequeue());
for (temp3 = 1; temp3 <= temp2; temp3++) param.Enqueue(reverser.Pop());
for (temp3 = 1; temp3 <= temp1; temp3++) param.Enqueue(frontHolder.Dequeue()); }
(scratch paper)