Linked Lists CS212 Dick Steflik Linked Lists A

  • Slides: 22
Download presentation
Linked Lists CS-212 Dick Steflik

Linked Lists CS-212 Dick Steflik

Linked Lists A sequential collection of information Can be unordered; i. e. in no

Linked Lists A sequential collection of information Can be unordered; i. e. in no specific order Can be ordered; may be organized in ascending or descending order based on some specific piece of information called a key List header contains : a link to the first node A link to the last node Other optional info (size) List is made up of items called a node which contains: The key Other pertinent information A field called a link that indicated the location of the next node

Unordered List Head Tail Size 4 Add. At. Front() Add. At. Tail() Take. From.

Unordered List Head Tail Size 4 Add. At. Front() Add. At. Tail() Take. From. Front() Take. From. Tail()

Unordered Lists Stacks and Queues are special cases of unordered lists An unordered list

Unordered Lists Stacks and Queues are special cases of unordered lists An unordered list where only Add. At. Front and Take. From. Front are used is a stack An unordered list where only Add. At. Front() and. Take. From. Rear() are used is a queue

Ordered List Head Tail Size 4 2 7 5 Insert() Take() Key Delete() Info

Ordered List Head Tail Size 4 2 7 5 Insert() Take() Key Delete() Info Link Find() 9

Representations Static usually used on systems without dynamic allocation Array based list of static

Representations Static usually used on systems without dynamic allocation Array based list of static nodes Struct Dynamic Array Collection of dynamically allocated nodes use when you have no idea of how big or small the list will ultimately be

Static Array Based int front, rear , cursor; item list[MAXSIZE] ; Problem: a lot

Static Array Based int front, rear , cursor; item list[MAXSIZE] ; Problem: a lot of data movement especialy on inserts or add at front Static Struct Based typedef struct { int front, rear , cursor; item data[MAXSIZE]; } list Problem: same as above

Array of Nodes typedef struct { item v; int next; } node; typedef struct

Array of Nodes typedef struct { item v; int next; } node; typedef struct { int front , freelist , cursor; node } list; data[MAXSIZE];

lets say that an item is just an int so a node is just

lets say that an item is just an int so a node is just a struct of two ints and the list is an array where each element is two ints (it kinda looks like a 2 dim array) , but we will treat it as if it were two lists; a list of unused nodes and a list of nodes in use next front -1 1 2 free cursor 0 3 4 5 6 7 -1 to initialize the list(s) as empty, link all of the nodes to gether set free to point at the first free node and set front to -1 to indicate that the list is empty. There are two lists; a list of free nodes that has all of the nodes and a empty list that has no nodes

to insert a node insert(7) take the free pointer and put it in front

to insert a node insert(7) take the free pointer and put it in front next front 0 7 -1 3 replace the next pointer of the front node with -1 to indicate it is the end of the list 4 put the data (7) in the front node 2 free cursor 1 take the next pointer of the front node an put it in free 5 6 7 -1 Now the list has one node in it and the free list is one node shorter

allocate Lets call this process of moving a node from the free list to

allocate Lets call this process of moving a node from the free list to the list “allocate”; it should always move the node at the front of the freelist to wherever a new piece of data is to be added (front, back or middle i. e. between two nodes). Every insert should start off by allocating a node, then inserting it into the list and finally putting the data into it This is exactly like using malloc to allocate dynamic node from the system heap, malloc and free allow the OS to manage the memory. In the absence of an OS (embedded systems) you have to do this yourself

deallocate This is the process of moving a node from the list back to

deallocate This is the process of moving a node from the list back to the free list and is functionally the same as the free operation used to move unneeded memory back to the system heap. In the case of deleting a node from the list the process consists of two steps; find the node to be deleted then deallocate it Note that deleting a node will effect the next pointers of the node preceding it and that the list will now be one node shorter. The deallocated node should always be added at the front of the free list making it one node longer

Linked List Improvements Header Node if instead of using a variables for the front

Linked List Improvements Header Node if instead of using a variables for the front pointer we use a node that contains no information (dumy node) that just points to the first node then insertion into an empty list and insertion at the end of the list look the same and eliminate one of the 3 special cases (front, back and middle) that need to be checked for

cursor = id->front; cursor while (id->Nodes[cursor]. next != NULL) cursor = id->Nodes[cursor]. next; front

cursor = id->front; cursor while (id->Nodes[cursor]. next != NULL) cursor = id->Nodes[cursor]. next; front //insert after cursor dummy t = allocate(); id->Nodes[t]. next = NULL; cursor front id->Nodes[cursor]. next = t; dummy See how the empty case and the end case look the same…

Another Improvement Make the list circular with a dummy header node If the dummy

Another Improvement Make the list circular with a dummy header node If the dummy header node initially points at itself then the insertion of the first node looks like its between the front and back List is empty when front = dummy. next

cursor front dummy cursor = id->front; while (id->Nodes[cursor]. next != NULL) cursor = id->Nodes[cursor].

cursor front dummy cursor = id->front; while (id->Nodes[cursor]. next != NULL) cursor = id->Nodes[cursor]. next; //insert after cursor t = allocate(); id->Nodes[t]. next = NULL; id->Nodes[cursor]. next = t; cursor front this again simplifies insertion and deletion as the action is always taking place between two nodes dummy

Doubly Linked Lists each node has two pointers one to the predecessor one to

Doubly Linked Lists each node has two pointers one to the predecessor one to the successor this simplifies insert and delete as you always have a pointer to the predecessor you don’t have to drag an extra pointer behind the cursor to keep track where the predecessor is The cost of this is one additional pointer per node two additional assignment instructions

prev next // inserting t = allocate(id); cursor pv = id->Nodes[cursor]. prev ; id->Nodes[pv].

prev next // inserting t = allocate(id); cursor pv = id->Nodes[cursor]. prev ; id->Nodes[pv]. next = t; id->Nodes[cursor]. prev = t ; id->Nodes[t]. next = cursor ; id->Nodes[t]. prev = pv t cursor // deleting pv = id->Nodes[cursor]. prev ; nx = id->Nodes[cursor]. next ; id->Nodes[pv]. next = nx ; id->Nodes[nx]. prev = pv ; deallocate(cursor)

DLL Improvements Make it circular eliminates special cases for empty list and adding at

DLL Improvements Make it circular eliminates special cases for empty list and adding at the end of list

Multilists if a list needs to be sorted by different key values for various

Multilists if a list needs to be sorted by different key values for various reasons add an additional next pointer for each sorting insert then inserts a node into several list at the same time can get very complicated very quickly but can be very useful if you need data sorted multiple ways

Sparse Arrays Another use for linked lists is to represent sparse arrays needs two

Sparse Arrays Another use for linked lists is to represent sparse arrays needs two forward links per node one for row pointer one for column pointer

2000 4003 0000 8001 0060 typedef enum {head, entry} tagfield; typedef struct matrix. Node

2000 4003 0000 8001 0060 typedef enum {head, entry} tagfield; typedef struct matrix. Node *matrix. Pointer; typedef struct entry. Node { int row; int col; int value; }; typedef struct matrix. Node { matrix. Pointer down; martix. Pointer right; tagfield tag; union { matrix. Pointer next; entry. Node entry; } u; matrix. Pointer hdnode[MAXSIZE];