Dummy Nodes, Doubly Linked Lists and Circular Linked Lists
Dummy Nodes
Plain Linked List Linked List has annoying special cases: InsertAt(index, value) If index = 0 InsertFirst(value) Else Node* newNode = new Node(value) Node* temp = head Repeat (index – 1) times temp = temp->next If temp == nullptr error newNode->next = temp->next temp->next = newNode
Plain Linked List Empty List: List with 1 value: Solution : Dummy Node ListNode that head always points to Created at construction, does not count in length Empty List: List with 1 value:
Plain Linked List Eliminates special cases InsertAt(index, value) Node* newNode = new Node(value) Node* temp = head Repeat index times temp = temp->next If temp == nullptr error newNode->next = temp->next temp->next = newNode
Linked List Directional Challenges
BigO's What is BigO for our improved linked list operations? O(1) O(1) With length & tail Get Length Insert Start Insert at InsertEnd Retrieve Retrieve Remove Remove middle First / L ast Middle Beginning End Value Value O(1) O(1) O(n) O(1) O(1) O(n) O(1) O(n)
Retrieve First / Last Value BigO's What is BigO for our improved linked list operations? With length & tail Get Length Insert Start Insert at middle InsertEnd Retrieve First / Last Value Retrieve Middle Value Remove Beginning Remove End O(1) O(1) O(n)
Reverse Traverse What if we want to reverse through the list? E.g. Print in reverse order
Reverse Traverse What if we want to print the list in reverse order? Iterative: for(i = length-1 … 0) cout << retrieveAt(i) BigO?
Reverse Traverse What if we want to print the list in reverse order? Iterative: for(i = length-1 … 0) //O(n) cout << retrieveAt(i) //O(n) BigO? O(n2)
Lesson Access middle: Avoid retrieveAt(i) in linked list! ArrayList : O(1) LinkedList : O(n) Avoid retrieveAt(i) in linked list!
Doubly Linked Lists
Doubly Linked Node Doubly linked node Pointers to previous and next
Doubly Linked List Doubly Linked List
With Dummies Dummy/Sentinel nodes to avoid special cases
Construct Valid starting state Head/Tail dummy nodes Head Tail prev : null next : tail Tail prev : head next : null Length : 0
Inserting InsertAt(index, value) : Insert(0, 8) previous = head repeat index times previous = previous->next make newNode
Inserting InsertAt(index, value) : Insert(0, 8) previous = head repeat index times previous = previous->next make newNode attach newNode to prev and prev->next
Inserting InsertAt(index, value) : Insert(0, 8) previous = head repeat index times previous = previous->next make newNode attach newNode to prev and prev->next attach newNode neighbors to newNode
Inserting InsertAt(index, value) : Insert(0, 8) previous = head repeat index times previous = previous->next make newNode attach newNode to prev and prev->next attach newNode neighbors to newNode update length
Inserting InsertAt(2, 15) previous = head repeat index times previous = previous->next make newNode attach newNode to prev and prev->next attach newNode neighbors to newNode update length
Inserting InsertAt(2, 15) previous = head repeat index times previous = previous->next make newNode attach newNode to prev and prev->next attach newNode neighbors to newNode update length
Inserting InsertAt(2, 15) previous = head repeat index times previous = previous->next make newNode attach newNode to prev and prev->next attach newNode neighbors to newNode update length
Inserting InsertAt(2, 15) previous = head repeat index times previous = previous->next make newNode attach newNode to prev and prev->next attach newNode neighbors to newNode update length
Removal RemoveAt(index) : RemoveAt(1) if index < 0 or index >= length, error current = head->next repeat index times current = current >next attach current's neighbors to each other delete current update length
Removal RemoveAt(index) : RemoveAt(1) if index < 0 or index >= length, error current = head->next repeat index times current = current >next attach current's neighbors to each other delete current update length
Removal RemoveAt(index) : RemoveAt(1) if index < 0 or index >= length, error current = head->next repeat index times current = current >next attach current's neighbors to each other delete current update length
Removal RemoveAt(index) : RemoveAt(1) if index < 0 or index >= length, error current = head->next repeat index times current = current >next attach current's neighbors to each other delete current update length
Final BigO Big O's for Doubly Linked O(1) O(1) O(n) Get Length Anything at start or end Anything in middle Forward Traversal of list Reverse Traversal of list O(1) O(1) O(n)
Circular List Circular linked list Last node links back to first Used to model domains, not for efficiency
Doubly Linked Tasks Implement: Constructor InsertAt RemoveAt