You are on page 1of 10

SAMPLE SHORT ANSWER QUESTIONS AND MULTIPLE CHOICE QUESTIONS

CHAPTER 5: Linked Lists A. Short Answers: 1. Two possible answers: a. head_ptr = new node(entry, head_ptr); b. list_head_ptr(head_ptr, entry); 2. The steps to removing the node after *p are: a. Initialize a new pointer to point to the node after p. b. Set ps link to the node that the new pointers links link points to. c. Delete the node pointed to by the new pointer. 3. The code is as follows: a. node *cursor; b. for(cursor = head_ptr; cursor!= NULL;cursor = cursor->link()) c. cout << cursor->data() << endl; 4. The statement is as follows: a. locate_ptr = locate_ptr->link(); 5. The new implemented function is as follows: a. size_t count_42s(const node* head_ptr) b. { c. node *cursor; d. size_t answer = 0; e. for(cursor = head_ptr; cursor != NULL; cursor = cursor->link()) f. { g. if(cursor->data() == 42) h. answer++; i. } j. return answer; k. } 6. The new implemented function is as follows:
a. bool has_42(const node* head_ptr) b. { c. node *cursor; d. for(cursor = head_ptr; cursor != NULL; cursor = cursor->link()) e. if(cursor->data()==42) f. return true; g. return false; h. }

7. The new implemented function is as follows:


a. bool all_42s(const node* head_ptr) b. { c. node *cursor; d. for(cursor = head_ptr; cursor != NULL; cursor = cursor->link()) e. if(cursor->data()!=42) f. return false; g. return true; h. }

8. The new implemented function is as follows:


a. int sum(const node* head_ptr) b. {

c. d. e. f. g.

node *cursor; int sum = 0; for(cursor = head_ptr; cursor != NULL; cursor = cursor->link()) sum += cursor->data(); return sum;

h. } 9. The new implemented function is as follows:


a. b. c. d. e. f. g. int sum(const node* head_ptr) { node *cursor; int product = 1; for(cursor = head_ptr; cursor != NULL; cursor = cursor->link()) product *= (cursor->data()); return product; }

h. 10. The new implemented function is as follows:

a. void list_tail_insert(node* head_ptr, const node::value_type& entry) b. { c. assert(head_ptr != NULL && tail_ptr != NULL) d. node *insert_ptr; e. insert_ptr = new node(entry, NULL) f. tail-ptr->set_link(insert_ptr); g. tail-ptr = insert_ptr; h. }

11. The new implemented function is as follows:


a. bool data_is_on(const node* head_ptr, const node* p) b. { c. node *cursor; d. for(cursor = head_ptr; cursor != NULL; cusor = cursor->link()) e. { f. if(cursor->data() == p->data()) g. return true; h. } i. return false; j. }

12. The new implemented function is as follows:


a. bool is_on(const node* head_ptr, const node* p) b. { c. node *cursor; d. for(cursor = head_ptr; cursor != NULL; cursor = cursor->link()) e. { f. if(cursor->link() == p->link()) g. return true; h. } i. return false; j. }

13. The new implemented function is as follows:


a. void list_insert_zero(node* previous_ptr) b. { c. node *insert_node; d. insert_node = new node; e. insert_node->set_data(0); f. insert_node->set_link(previous_ptr->link()); g. previous_ptr->set_link(insert_node); h. }

14. The new implemented function is as follows:


a. node *x; node *y; node *z; b. list_copy(p, x, z); c. y->set_link(list_locate(x, 8));

15. The expression a_ptr == b_ptr will be true when the node pointers a_ptr and b_ptr link to the same node. 16. The worst-case big-O time analysis for the insert function for the bag using a fixed-sized array is O(1) while the worst-case big-O time analysis for the insert function for the bag using a linked list is O(1). Therefore, nither case is more efficient than the other. 17. The worst-case big-O time analysis for the erase_one function for the bag using a fixed-sized array is O(n) while the worst-case big-O time analysis for the erase_one function for the bag using a linked list is O(n). Therefore, neither is more efficient than the other. 18. If there is no current node, then the attach function places the entry at the end of the list, which is why it is efficient to have a tail pointer to use. A specific example is: It is more efficient to have a tail pointer because we do not have to traverse through the list (O(n)) and can rather access the tail quite easily and, in constant time, can insert the entry using the tail pointer. 19. To insert an entry into a linked list, we have to be able to refer to the node before the current node, which is done by using a precursor pointer. An example is the following: If we had to insert a 5 into a linked list of 10, 20, 30, 40 where 20 was the current node, we could easily use the precursor, which would be pointing at 10 to manipulate the links and do so. However, if we do not have a precursor, we would have to find the node before the current node using a function and only then would we be able to insert the entry at the desired position. Therefore, we avoid having an O(n) complexity by being able to insert an entry in constant time, O(1), using the available precursor reference. 20. The worst-case big-O time analysis for the insert function for the bag using a fixed-sized array is O(n) while the worst-case big-O time analysis for the insert function for the bag using a linked list is O(1). Therefore, insertions are more efficient in a linked list. 21. The worst-case big-O time analysis for the remove function for the bag using a fixed-sized array is O(n) while the worst-case big-O time analysis for the remove function for the bag using a linked list is O(n) as well. 22. A doubly linked list is better when we require a cursor than can move forward and backward in a list. Such a cursor is also known as a two-way cursor, due to this behavior. 23. Storing elements in an array is clearly better than storing items in a linked list when we need to refer to specific locations within the array, for example, index 42 or maybe index 6. In such a case, we would be able to store an element into a specific index in constant time, howver, using a linked list, we would have to first find that position and only then would we be able to store anything there. Therefore, it is clearly better to use arrays for the purpose of storing items at specific positions or indices. 24. The function is implemented as follows:
a. int sum_data(const dnode* head_ptr) b. { c. dnode *cursor; d. int sum = 0; e. for(cursor = head_ptr; cursor != NULL; cursor = cursor->link()) f. sum = sum + cursor->data(); g. return sum; h. }

B. Multiple Choice: 1. D 2. B 3. B 4. D 5. D 6. D 7. A

8. 9. 10. 11. 12. 13.

A A E B C F

The bag does not have the private member many_nodes, but the sequence does. 14. A 15. C 16. A

CHAPTER 6: Template Functions, Template Classes, and Iterators A. Short Answers: 1. The advantages of template functions include being able to reuse the same function in the same program, or multiple different programs, witch varying data types. For example, the function could be called having a char parameter, int parameter, etc. all in the same program. This enables the programmer to save time by not writing out different functions for the same operation just because of different data type needs. 2. The template parameter must appear in the parameter list of the template function because the compiler needs to figure out how to instantiate the template function and without doing so it would run into a failed unification error. 3. The bug is that each time an element is copied and moved to the next index, the element already in that index is overwritten and lost. Therefore, once the loop has finished running, the array will just be filled with whatever was in index 0. A correct implementation of the code that moves every element an index ahead would be:
i. size_t i; ii. for(i = n; i > 0; i++) iii. data[i] = data[i - 1];

4. It is a bad idea to have a size_t parameter for a template function because some compilers do not recognize size_t and int as an exact match. 5. One place where the word bag remains just bag instead of changing to bag<Item> is when it is used as an argument in funcitons in the namespace definition of the header file. 6. The advantages of using template classes are essentially the same as the advantages of using template funcitons. When using template classes, they are dependant upon an underlying data type, and objects holding the same properties but using different unedrlying data types can be declared and used in the same program. 7. * The implemented function is as follows: i. template <class Item> ii. void list_head_remove(node<Item>*& head_ptr) iii. { iv. node<Item> *cursor; v. cursor->set_link(head_ptr->link()); vi. cursor->set_data(head_ptr->data()); vii. delete [] head_ptr; viii. head_ptr = cursor; ix. } B. Multiple Choice: 1. A 2. B 3. C 4. B 5. B 6. B 7. B 8. B 9. A 10. E 11. C 12. D 13. B

CHAPTER 7: Stacks A. Short Answers: 1. To make the parentheses matching algorithm check expressions with different kinds of parentheses, we would merely have to replace all instances of ( with the left parenthesis of choice, and replace all instances of ) with the right parenthesis of choice. 2. The implemented function is as follows:
i. #include<stack>; ii. bool balanced(const char p[], size_T n) iii. { iv. const char LEFT_PARANTHASES = '('; v. const char RIGHT_PARANTHASES = ')'; vi. const char LEFT_BRACKET = '{'; vii. const char RIGHT_BRACKET = '}'; viii. stack<char> jar; ix. char next; x. for(size_t i = 0; i < n; i++) xi. { xii. next = p[i]; xiii. if(next == LEFT_PARANTHASES || next == LEFT_BRACKET) xiv. jar.push(next); xv. else if(next == RIGHT_PARANTHASES) xvi. { xvii. if(jar.top() == LEFT_PARANTHASES) xviii. jar.pop(); xix. else xx. return false; xxi. } xxii. else if(next == RIGHT_BRACKET) xxiii. { xxiv. if(jar.top() = LEFT_BRACKET) xxv. jar.pop(); xxvi. else xxvii. return false; xxviii. } xxix. return true; xxx. } xxxi. }

used = 2, data: [1, 2, , , ] head_ptr 1 2 tail_ptr * in development The stack for the case where the 11th symbol is: i. A number: *, (, + ii. A left parenthesis: *, (, +, ( iii. A right parenthesis: * iv. A minus sign: *, (, v. A division sign: *, (, +, / B. Multiple Choice: 1. D 2. D 3. C 4. B 5. D 6. C 7. A

3. 4. 5. 6.

8. 9. 10. 11. 12. 13. 14. 15. 16.

C B D B A E E E D

CHAPTER 8: Queues A. Short Answers: 1. The implemented function is as follows:


i. ii. iii. iv. v. vi. vii. viii. ix. x. xi. xii. xiii. xiv. xv. xvi. xvii. size_t answer = 0; queue q; char letter; while(cin.peek() = '\n') { cin >> letter; q.push(letter); } const cha L = letter; while(!q.empty()) { if(q.front()=L) answer++ q.pop(); } return answer; xviii. }

2. First = 1, data: 1, 2, 3, , 3. front_ptr 1 , 3 rear_ptr 4. It is a bad idea to implement a linked list version of a queue which uses the head of the list as the rear of the queue because it becomes difficult to remove an item from the list. While doing so, it would be necessary to have front_ptr point to the second item in the queue and there is no easy of accomplishing this unless the whole list was traversed from the rear to the front to find this node. 5. The insert member function simply will place the new entry at the tail of the linked list. 6. B. Multiple Choice: 1. C 2. D 3. C 4. D 5. C 6. B 7. D 8. D 9. C 10. B 11. C 12. D 13. A

CHAPTER 9: Recursion A. Short Answers: 1. The importance of the stopping case in recursive functions is to ensure that there will come a time when the function will not need to use further recursion, but will just be able to use a stopping case to end the function call. This is necessary because, without it, the function would end up making infinite recursion calls, never end, and not be useful in any way. 2. The implemented function is as follows:
i. ii. void recursion(size_t x) iii. { iv. if(x > 0) v. { vi. cout << "*" << endl; vii. recursion(x - 1); viii. } ix. cout << "!" << endl; x. }

3. The implemented function is as follows:

i. void pattern(unsigned int n) ii. { iii. if(n > 0) iv. { v. if(n/2 > 4242) vi. return; vii. else viii. { ix. cout << n << endl; x. pattern(2*n); xi. } xii. cout << n << endl; xiii. } xiv. else xv. return; xvi. }
4. The implemented function is as follows:

i. void recursion(unsigned int m, unsigned int n) ii. { iii. if( 0 > m) iv. return; v. else if( m > n) vi. return; vii. else viii. { ix. for(unsigned int i = 1; i <= m; i++) x. cout << "*"; xi. cout << "\n"; xii. recursion(m + 1, n); xiii. xiv. for(unsigned int i = 1; i <= m; i++) xv. cout << "*";

xvi. xvii.

cout << "\n"; }

xviii. } B. Multiple Choice: 1. D 2. D 3. C 4. A 5. C 6. Question is not appropriate 7. C 8. D 9. A 10. E 11. A 12. optional 13. optional 14. optional 15. optional 16. C