1 Data Organization Example 1: Heap storage management Maintain a sequence of free chunks of memory Find an appropriate chunk when allocation is requested Remove a chunk off the list when it is allocated. Put a chunk back in the list when it is deallocated Example 2: A simple text editor Maintain a sequence of lines Example 3: Graph representation (e.g. network) For each vertex, maintain a list of its neighbors.
2 Data Organization All these examples have a common organizational model: A sequence of similar items (memory blocks, text lines, vertices) Certain desired operations find, insert, delete
3 Data organization Major components: The data The operations allowed on it These make up an Abstract Data Type A Data Structure is a construct that implements a particular ADT.
4 The List ADT Data: a collection of homogeneous elements arranged in a sequence Operations: Insert Delete Find Update Retrieve Length
5 The List ADT: Operations General access Which element? Idea 1: Specify an index The user will be able to give an index and perform an operation on the element at that index. Idea 2: Use a pointer to the current location The user is only given access to the element where the current pointer points. What additional operations will be needed to support this?
6 The List ADT: Operations General access Which element? Idea 1: Specify an index The user will be able to give an index and perform an operation on the element at that index. Idea 2: Use a pointer to the current location The user is only given access to the element where the current pointer points. What additional operations will be needed to support this? At the very least, an Increment and Decrement operation to move the current pointer to a new location.
7 The List ADT: Operations Retrieve Which element? Specify an index : Retrieve(i) The user will be able to give an index and retrieve the element at that index. Use a pointer to the current location : Retrieve() The user will have to move the current pointer to the requested element and then retrieve it.
8 The List ADT: Operations Insert Where? Specify an index : Insert(i, value) Insert an element at index i. The existing element at that index will move to i+1 Use a pointer to the current location : Insert(value) Insert an element at the current location. The user will need to move the pointer to that location first. What complications arise in this case?
9 The List ADT: Operations Insert Where? Specify an index : Insert(i, value) Insert an element at index i. The existing element at that index will move to i+1 Use a pointer to the current location : Insert(value) Insert an element at the current location. The user will need to move the pointer to that location first. Inserting an element at the end is problematic: how do we move the current pointer to a location that doesn't exist? We'll need some sort of "dummy" element at the end of the list. But this introduces more complications!
10 The List ADT: Operations Insert Where? Specify an index : Insert(i, value) Insert an element at index i. The existing element at that index will move to i+1 Use a pointer to the current location : Insert(value) Insert an element at the current location. The user will need to move the pointer to that location first. Inserting an element at the end is problematic: how do we move the current pointer to a location that doesn't exist? We'll need some sort of "dummy" element at the end of the list. But this introduces more complications! The Retrieve operation is not defined for that dummy element.
11 The List ADT: Operations Insert Where? Use a pointer to the current location : Insert(value) Insert an element at the current location. The user will need to move the pointer to that location first. Inserting an element at the end is problematic: how do we move the current pointer to a location that doesn't exist? Idea: "Dummy" element at the end of the list. Alternative 1 : provide a special InsertAtEnd() operation. Is this a good idea? Alternative 2: provide InsertBefore(), InsertAfter(). Is this a good idea?
12 The List Data Structure Implementation 1 : Contiguous memory Use a dynamic array with a current pointer How is each operation implemented? How efficient is each operation? Random access capability good for retrieval when we use index rather than current pointer. Important: the list ADT does NOT provide random access. We just use it internally to speed up retrieval. We will need to shift elements every time we insert or delete. In addition, if the array fills up, we need to reallocate a bigger chunk of memory.
13 The List Data Structure Implementation 2 : Singly-linked memory Use a node structure to store the data and a pointer to the next node, to create a chain of nodes. Use a current pointer Uses more space than the array (due to the pointers) but insert/delete do not require shifting. However, insert / delete require us to traverse the whole list in order to access the predecessor of the current node. Can we avoid this?
14 The List Data Structure Implementation 2 : Singly-linked memory insert / delete require us to traverse the whole list in order to access the predecessor of the current node. Trick solution (works for deleting any node but the last): move the next node's contents into the one to be deleted and then physically remove the next node. This maintains the correct abstract picture of the structure. We can use a similar trick for the insert operation. Using this method makes insert/delete take constant time in all cases except when inserting/deleting the last node. That takes linear time.
15 Other list flavors Doubly-linked list Each node has a pointer to its successor and its predecessor. Faster insert/delete, but more space. Circular list The last node points back to the head (or the array wraps around). Sorted list Items stored in sorted order. Which implementation provides faster operations? Array or linked memory?
16 Other list flavors XOR list A space saving list Instead of both a previous and next pointer, store the XOR of the predecessor and successor. Node B stores &A XOR &C If you are at B and know the address of A, you can compute the address of C. The list can be traversed in any direction, provided you know where you came from. Interesting, but not very useful...
17 Other list flavors Unrolled linked list A space saving list Store k data items in each node It's a list of arrays Reduces cache misses Each node should be at least half-full If a node is too empty after a delete, merge it with a neighbor. If a node overflows after an insert, split it.
18 Implementing our ideas template class LinkedList { private: class Node { public: Node *next; Node *prev; T item; Node(); Node(T element, Node *nextcell = NULL, Node *prevcell = NULL); ~Node(); }; Node *head; Node *current; public:... };