180 likes | 459 Views
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
E N D
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.
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
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.
The List ADT • Data: • a collection of homogeneous elements arranged in a sequence • Operations: • Insert • Delete • Find • Update • Retrieve • Length
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?
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.
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.
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?
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 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.
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?
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.
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?
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.
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?
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...
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.
Implementing our ideas template <class T> 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: ... };