We encountered several linked representations for a sequence of values over the past three labs.
- The first approach was to represent all the values in the sequence with
ListNodes, each storing a sequence value and a reference (pointer). The reference is to the
ListNodestoring the next value in the sequence. A problem is that in this representation, there's no way to represent an empty sequence.
- To fix this, we created an
EmptyListNodeclass and renamed the
NonemptyListNode. Both have the same set of methods (though obviously not the same set of behaviors), suggesting that they both inherit from an abstract class. Using this representation, we implemented several list operations.
- There was still the problem of insufficient information hiding. If any
ListNodeobject is accessible in the rest of the program, they all are, and a programmer might accidentally leave a value in an invalid state. The solution is to invent a second class,
List, that contains a reference to the first
ListNodein the sequence, the declaration of
ListNode(now a nested class), and various methods that restrict the inspection and manipulations of the list information.
We then went on to examine three variations of the "standard" linked list, namely a circular list (which links its last node to its first node), a doubly linked list (in which each node contains a reference to its next node and its previous node, and a list with a "dummy" header node. Circular lists are models for circular processes, e.g. a scheduler of jobs running on a computer; a circular list is also good for implementing a queue (topic to come). Doubly linked lists allows inserting a value into or deleting it from the list without using a trailing pointer. A dummy header makes the check for an empty list unnecessary.
The activities mostly involve implementing list operations in up to three ways. We hope that this solidified your understanding of linked representations rather than bored you.