Linked lists
January 20, 2020 Cinda Heeren / Andy Roth / Geoffrey Tien 1
Linked lists January 20, 2020 Cinda Heeren / Andy Roth / Geoffrey - - PowerPoint PPT Presentation
Linked lists January 20, 2020 Cinda Heeren / Andy Roth / Geoffrey Tien 1 Announcements HW1 due tonight! Only one partner in a group needs to submit See course webpage for details about page/question linking, and adding a partner to
January 20, 2020 Cinda Heeren / Andy Roth / Geoffrey Tien 1
– Only one partner in a group needs to submit – See course webpage for details about page/question linking, and adding a partner to the submission
– GradeScope configuration to follow shortly
January 20, 2020 Cinda Heeren / Andy Roth / Geoffrey Tien 2
– And we want to insert an item in a particular position in the middle
January 20, 2020 Cinda Heeren / Andy Roth / Geoffrey Tien 3
A motivation
12 15 16 19 22 28 34 37 41 46 17 All of these elements must be shifted over one at a time
Linked lists are a dynamic data structure that can achieve fast insertions/ deletions in the middle
January 20, 2020 Cinda Heeren / Andy Roth / Geoffrey Tien 4
– In C++ this is recorded as a pointer to a node
– And their memory locations are not in sequence
January 20, 2020 Cinda Heeren / Andy Roth / Geoffrey Tien 5
January 20, 2020 Cinda Heeren / Andy Roth / Geoffrey Tien 6
7 2 6 8 Start This symbol indicates a null pointer
January 20, 2020 Cinda Heeren / Andy Roth / Geoffrey Tien 7
Node class
class Node { public: int data; Node* next; };
next points to another node, hence its type Node*
– or the '->' (arrow) operator as a shorthand for pointer types
Node nd; nd.data = 5; Node* p = nd.next; (*p).data = 5; Node* q = *((*p).next).next; Node* r = q->next->next;
January 20, 2020 Cinda Heeren / Andy Roth / Geoffrey Tien 8
Node* a = new Node(7, null);
Assume we have written a parameterized constructor for the Node class 7 a
January 20, 2020 Cinda Heeren / Andy Roth / Geoffrey Tien 9
Node* a = new Node(7, null); a->next = new Node(3, null);
7 a 3
January 20, 2020 Cinda Heeren / Andy Roth / Geoffrey Tien 10
Node* a = new Node(7, null); a->next = new Node(3, null); Node* p = a; p = p->next; // go to next node p = p->next;
7 a 3 p
January 20, 2020 Cinda Heeren / Andy Roth / Geoffrey Tien 11
… 15 16 19 22 28 a p
Node* b = new Node(17, p->next);
17 b
p->next = b;
Important! Be aware that sequential nodes are not guaranteed to be found in sequential memory locations!
– but remember to delete the removed node!
… 15 16 19 22 28 a p b
p->next = b->next; delete b;
January 20, 2020 Cinda Heeren / Andy Roth / Geoffrey Tien 12
– operations at the back of the list have (relatively) poor complexity, requiring a traversal – but we can give ourselves a tail pointer for very little overhead, maintained during operations at the back of the list
January 20, 2020 Cinda Heeren / Andy Roth / Geoffrey Tien 13
class Node { public: int data; Node* next; Node(int d, Node* nd) { data = d; next = nd; } }; class LinkedList { private: Node* head; int length; public: LinkedList(); ... }; class LinkedList { private: Node* head; Node* tail; int length; public: LinkedList(); ... };
– What about insertion in the middle of the list? – What about removal from the back of the list?
January 20, 2020 Cinda Heeren / Andy Roth / Geoffrey Tien 14
Insertion at back of list
1 2 3 4 6 7 9 head tail new
– links to previous node in the list, allows traversal or access towards the front of the list
January 20, 2020 Cinda Heeren / Andy Roth / Geoffrey Tien 15
class Node { public: int data; Node* prev; Node* next; // constructors, etc. };
2 9 6 5 head
– but, requires more pointer management in programming
January 20, 2020 Cinda Heeren / Andy Roth / Geoffrey Tien 16
After some specified node
12 4 23 6 head
Node* curr, * temp; ... // use a loop to move curr into place temp = new Node(); temp->data = 7; temp->prev = curr; temp->next = curr->next; curr->next->prev = temp; curr->next = temp;
curr temp 7
January 20, 2020 Cinda Heeren / Andy Roth / Geoffrey Tien 17
At some specified node
12 4 23 6 head 7
Node* curr; ... // move curr to the node to be removed curr->next->prev = curr->prev; curr->prev->next = curr->next; delete curr; curr = NULL;
curr
– requires no change to the Node definition – circular property is maintained during operations
January 20, 2020 Cinda Heeren / Andy Roth / Geoffrey Tien 18
Singly-linked version
head 12 15 7
– address of next is the same as the address of the front – but still must be careful to do NULL check on empty list!
– what about inserting at the head? – need to iterate a pointer to the last node in the list!
January 20, 2020 Cinda Heeren / Andy Roth / Geoffrey Tien 19
Insertion at head
head 12 15 9 7 3
Node* ptr, * newnode; ptr = head; while (ptr->next != head) ptr = ptr->next; newnode = new Node(); newnode->data = 4; newnode->next = head; ptr->next = newnode; head = newnode;
newnode 4 ptr
– and the first node points to the last node
January 20, 2020 Cinda Heeren / Andy Roth / Geoffrey Tien 20
head 6 23 15 What is the time complexity of accessing the last element of a circular doubly-linked list?
– Background: 1.4, C1.1-C1.4 – C2.3, C2.5 (Pointers, dynamic arrays) – Chapter 4 (Linked lists)
– Carrano & Henry: Chapter 6 (ADT Stack)
January 20, 2020 Cinda Heeren / Andy Roth / Geoffrey Tien 21