```

```

## Fall 2009

### Instructions

1. Write your name clearly at the top of the exam

2. You must answer all the questions on the exam. The exam has 6 problems. Make sure that you have all 6 problems.

3. Write your answers on the exam pages and hand in the exam when you are finished.

4. You have until the end of the class period to finish the exam. When I call time you must immediately drop your pen/pencil and hand in your exam.

5. Ensure that you write clearly and legibly. Failure to do so may result in the deduction of points.

6. The exam is closed note, closed book, closed neighbor.

7. Good luck!

```

```

1. (20 points)
```
a. array
e. circular, array queue
f. stack
```

For each of the following questions choose the best answer from the above list. Assume that the size of an array is fixed once it is created, and that its size cannot be changed thereafter. Sometimes it may seem as though two or more choices would be equally good. In those cases think about the operations that the data structures support and choose the data structure whose operations are best suited for the problem. You may have to use the same answer for more than one question:

1. ____________ The most space-efficient data structure you could use to implement a stack in which there is an upper limit, max, on the number of elements that can be stored on the stack.
2. ____________ The most space-efficient data structure you could use to implement a stack in which the the number of elements that can be stored on the stack is unlimited.
3. ____________ The data structure which allows any of its elements to be accessed in constant time.
4. ____________ The data structure you would use if you needed to be able to delete an element in the middle of the data structure.
5. ____________ The data structure you would use to ensure that the last item added to the data structure is always the first item removed from the data structure.
6. ____________ The most space-efficient data structure you could use if you wanted to print out the last n lines of a file where n is a command-line argument.
7. ____________ The data structure you would use to check whether a set of parentheses were balanced in an expression.
8. ____________ The data structure you would use if you wanted to simulate an unbounded line of customers at a grocery store, where customers are served from the front of the line and customers enter at the back of the line.
9. ____________ The data structure that allows you to traverse its elements in either forward or reverse order.
10. ____________ The data structure that you could use to implement streaming video on a video card with a fixed amount of memory.

2. (16 points) Suppose I want to write a library package for a vector. A vector is an array that can be dynamically resized if it is not big enough. The library would worry about calling realloc so the user does not have to. I want to use information hiding to implement the vector library. My implementation will have two files named vector.h and vector.c. Answer the following questions:

1. I want to provide a function called new_vector that is passed the initial vector size as an integer parameter. Write the function declaration for new_vector (do not write the definition, just the declaration as it would appear in the .h file). I have intentionally not told you what the return value is. You should be able to figure it out based on the fact that I want you to use information hiding.
```

```
2. _______________________ I want my vector to be able to store generic data. What should be the type of the value that it stores. For example, if I have the function description:

void vector_set(? vector, int index, ? value): Sets the entry at the specified index to value.

what should be the declared type of value? That is what should the ? before value be replaced by? (Please do not tell me the type of vector--the question mark before vector is there because I do not want to give away the answer to question a).

3. Where should the structs for the vector's implementation be declared. Put a check mark next to the appropriate answer:

1. __________ vector.h

2. __________ vector.c

3. __________ the user's .c file
```

```
4. (Problem 2 continued) Declare a struct for the vector's container object. Use a typedef to name the struct "vector". You need to figure out what fields the struct needs and then declare them. Hint: The container object will need to have a pointer to something that holds the vector's data, it will need to keep track of its capacity and it will need to be able to figure out when it must resize itself.
```

```
3. (12 points) You have a circular queue with a capacity of 8 elements. For each of the following two subparts, show what the contents of the array will be after the specified sequence of enqueue and dequeue operations, and show where the front and back indices will point. If an array entry is empty, either because it has never been filled, or because its value has been dequeued, then leave its box blank.
1. ```enqueue(6);
enqueue(5);
enqueue(3);
enqueue(2);
dequeue();
dequeue();

0     1     2     3     4     5     6     7
-------------------------------------------------
|     |     |     |     |     |     |     |     |
|     |     |     |     |     |     |     |     |
-------------------------------------------------
```
2. Now you receive the following additional set of enqeueue and dequeue operations. Show the contents of the array and where the front and back pointers point after these additional operations have been applied to the queue (i.e., do not start from scratch but build on the queue that you started in the previous part).
```enqueue(7);
enqueue(8);
enqueue(2);
enqueue(11);
dequeue();
dequeue();
enqueue(9);

0     1     2     3     4     5     6     7
-------------------------------------------------
|     |     |     |     |     |     |     |     |
|     |     |     |     |     |     |     |     |
-------------------------------------------------

```
4. (16 points) Consider the following declarations and function: push(int i, Stack *s); // push an integer i onto s int pop(Stack *s); // pop an integer off s and return its value bool isEmpty(Stack *s); // return true if the s is empty and false otherwise int mystery(Stack *stack) { char token; int count = 0; int x; while (scanf("%c", &token) != EOF) { if (token == '{') { count++; push(count, stack); } else if (token == '}') { if (isEmpty(stack)) return 0; else x = pop(stack); } // any character other than a '{' or a '}' is ignored } if (isEmpty(stack)) { return -1; } else return pop(stack); } Suppose the input is:
```{ hi { brad { how } { are } { you
```
1. What is the contents of stack after the second } is read? Some of your entries may be empty. Fill the stack from bottom to top:
```     ______________
|            |
|            |
--------------
|            |
|            |
--------------
|            |
|            |
--------------
|            |
|            |
--------------
|            |
|            |
--------------

```
2. Given this input, what does mystery return? _____________

3. (problem 4 continued) mystery is checking something. What is it checking for?
```

```
4. mystery returns three different values--0, -1, or x--depending on the outcome of its check. How would your calling program interpret each of these return values? That is, if your program had to print a message explaining the meaning of the return value, what would it say. Be concise (you may want to defer this question to the end of the test because you might have to devise a couple sample input sequences to figure it out and that could take some time).

1. 0:
```

```
2. -1:
```

```
3. x:
```

```
5. (16 points) Behold the following struct, which contains a union:
```struct account {
int type;
char name[30];
double balance;
union {
struct {
int check_num;
char *checks;
} checking;
struct {
double interest_rate;
double quarterly_interest;
double annual_interest;
} savings;
};
};
```
1. _____________ How many bytes will be allocated to just the union field (i.e., acct_info)? You should make the following assumptions:

• ints and pointers are 4 bytes
• doubles are 8 bytes
• a single char takes 1 byte
• fields are packed together as tightly as possible and word alignment is ignored.

2. _____________ How many bytes will be allocated to the entire struct (i.e., the account struct)?

3. Suppose I have the declaration:
```struct account y;
```
Write expressions to:

1. copy the string "bvz" to the name field.
```
```
2. assign 30 to the check_num field of checking.
```
```
3. copy the string "Smiley" to the checks field of checking.
```
```
4. assign .05 to the annual_interest field.
```

```

6. (20 points) You are given a singly linked list, L, of integers and an array P, containing integer indices sorted in ascending order. The function createList(L, P, Psize) will create and return a new list that contains the elements in L that correspond to the positions specified by P. For instance, if P = 1, 3, 4, 6, and L is the list:
```L -> 6 -> 20 -> 8 -> 25 -> 30 -> 41 -> 66 -> 10 -> 20
```
then your new list will be:
```new_list -> 20 -> 25 -> 30 -> 66
```
which, using zero-based indexing, correspond to the elements at index locations 1, 3, 4, and 6 in L. Write the procedure createElements(L,P,Psize) using my sllist library. In case you have forgotten, I have attached the interface for the sllist library to the end of the exam.

1. L is a pointer to an Sllist.
2. P is a pointer to an integer array.
3. Psize is the size of the integer array.
4. The return value is a pointer to an Sllist.
5. You may assume that P does not have integer indices that are larger than the number of elements in L. Hence you do not need to check whether you have run past the end of L.
6. For maximum points, you should take advantage of the fact that P is in ascending order and traverse L only once. If you cannot figure out how to do this, you can traverse L multiple times for 16 points.
7. You need to show me your function declaration and definition. Do not show me include files, statements to read data, etc. L and P have been prepared for you by the calling function.
```

```

## Sllist Library

• Sllist *new_sllist(): Allocates and returns a container object for a new singly linked list.
• void free_sllist(Sllist *l): Destroys the list, calling free() on all allocated memory in the list. The list does not have to be empty.
• Sllist_Node *sll_prepend(Sllist *l, void *val): Adds a new node at the beginning of the list. This node's value is val, and a pointer to the node is returned.
• Sllist_Node *sll_append(Sllist *l, void *val): Adds a new node to the end of the list. This node's value is val, and a pointer to the node is returned.
• Sllist_Node *sll_insert_after(Sllist *l, Sllist_Node *n, void *val): Adds a new node to list l right after the specified node, n. This node's value is val, and a pointer to the node is returned. A pointer to the list's container object must be passed as an argument because the insertion algorithm may have to update the list's tail pointer, if the new node becomes the last element in the list.
• Sllist_Node *sll_first(Sllist *l): Returns a pointer to the first node in the list. If the list is empty, this returns NULL.
• Sllist_Node *sll_last(Sllist *l): Returns a pointer to the last node in the list. If the list is empty, this returns NULL.
• Sllist_Node *sll_next(Sllist_Node *n): Returns a pointer to the next node in the list after n. If n is the last node on the list, then sll_next(n) returns NULL.
• void *sll_val(Sllist_Node *n): Returns a pointer to n's value. You will need to cast this pointer to the appropriate type.
• int sll_empty(Sllist l): Returns whether l is empty.