Saint Louis University |
Computer Science 180
|
Dept. of Math & Computer Science |
Topic: Linked List Manipulations
Related Reading: Ch. 4.5-4.7, 5.3
Due:
Wednesday, 5 November 2008, 10:00am
Please make sure you adhere to the policies on academic integrity.
As we prepare for the coming exam, I have chosen as homework to take two questions that appeared on last year's exam. These involve the low-level manipulation of singly and doubly-linked lists.
In a previous lecture, we provided source code for an
implementation of a stack using a singly-linked list. That
code is essentially based upon the implementation given in
Chapter 5.3 of the text (however, our implementation
includes an explicit num_items variable).
Figure 5.4 on page 330 of the text shows a
schematics drawing of such a stack that results after pushing
the four
For this question suppose we redefined push slightly
differently. We write it as follows, yet with two lines
purposefully omitted.
void LinkedStack::push(const Item_Type& item) { // push element onto stack
Node* temp = new Node(item);
num_items++;
[-----------------]
[-----------------]
}
We want you to consider the following four candidates for
those missing lines. For each variant, provide an updated
version of Figure 5.4, as the state exists after
executing the call s.push('d').
As a hint, we will tell you that one of the four is legitimate
and the other three are flawed.
top_of_stack = temp; temp->next = top_of_stack;
temp = top_of_stack; top_of_stack->next = temp;
temp->next = top_of_stack; top_of_stack = temp;
top_of_stack->next = temp; temp = top_of_stack;
Chapter 4.7 provides a list class implementation based upon the underlying use of a doubly-linked list. Code for the erase function is given on pp. 277-278. The beginning of that body focusses on creating an interator as a return value and checking for special cases when erasing at the head or tail of the linked list. The return_value iterator is advanced to be the one after the pos iterator.
We wish to focus on the "normal" case that is handled by the remainder on page 278. It provides the following code fragment for unlinking and deleting the current node.
DNode* removed_node = pos.current; removed_node->prev->next = removed_node->next; removed_node->next->prev = removed_node->prev; delete removed_node;
Those middle two lines successfully relink the neighboring nodes to each other. Given the existing variables removed_node, pos and return_value, there are several more obfuscated ways that we could achieve the same goal. We want you to consider the following three alternatives. For each variant, provide an updated version of Figure 4.31 from page 278, as the state exists after executing the call erase(iter) upon that list. Some may be legitimate, some may be flawed.
removed_node->prev->next = removed_node->next; removed_node->prev->next->prev = removed_node->prev;
removed_node->prev->next->prev = removed_node->prev; removed_node->prev->next = removed_node->next;
DNode* follow = return_value.current; follow->prev = removed_node->prev; follow->prev->next = follow;
DNode* follow = return_value.current; follow->prev->next = follow; follow->prev = removed_node->prev;