
Chapter 19
Programming Problems Using Linked List
19.1 Queues . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 307
19.2 Sorting Numbers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 308
19.3 Sparse Arrays . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 308
19.4 Reversing a Linked List . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 314
19.1 Queues
The function List insert in Section 18.3 always inserts the new value at the beginning
of the list. If we always delete nodes from the front of the list, then the linked list is a
stack. In this problem we change the insert function so that the first inserted value is at
the beginning of the list and the latest inserted value is at the end of the list. If we still
remove elements from the beginning of the list we have created a queue, like a line at a store
waiting for service. The implementation below uses recursion.
Node * List_i nsert ( Node * head , i nt val )1
{2
i f ( head == NULL )3
{4
return Nod e_cons t ruct ( val ) ;5
}6
head -> next = List_i nsert ( head -> next , val ) ;7
return head ;8
}9
When the if condition is (when head is NULL), the list is empty. Every recursive call
moves forward by following the next link. This condition can be true if the function has
reached the end of the list. When the frame from the call stack is popped, the previous
node’s next is set to a pointer to the newly created node. For nodes not at the end, line 7
is essentially head -> next = head -> next without changing the list.
You may have noticed that this particular linked list implementation of a queue is not
efficient. Every time a node is inserted, the function has to go through the entire list to
reach the end of the list. This is unavoidable because the program only tracks the beginning
of the list. One solution is to keep track of both the beginning (the head) and the end (the
tail) of the list. This requires two pointers.
Another problem is that the links are uni-directional. When deleting a node, it is nec-
essary to keep track of the node before the node to be deleted. This inconvenience can be
solved by using two links in each node: next and previous. If q is p -> next, then p is
q -> previous. The head of the list has no previous node so its previous points to NULL.
The tail of the list has no next node so its next points to NULL. This is called a doubly linked
list. The structure definition for a node in a doubly linked list is shown below:
307