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 the submission • PA1 out – GradeScope configuration to follow shortly January 20, 2020 Cinda Heeren / Andy Roth / Geoffrey Tien 2
Linked lists A motivation • Imagine an array partially filled with data – And we want to insert an item in a particular position in the middle 17 12 15 16 19 22 28 34 37 41 46 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 3
Linked list nodes • A linked list is a dynamic data structure that consists of nodes linked together • A node is a data structure that contains – data – the location of the next node January 20, 2020 Cinda Heeren / Andy Roth / Geoffrey Tien 4
Node pointers • A node contains the address of the next node in the list – In C++ this is recorded as a pointer to a node • Nodes are created in dynamic memory – And their memory locations are not in sequence • The data attribute of a node varies depending on what the node is intended to store January 20, 2020 Cinda Heeren / Andy Roth / Geoffrey Tien 5
Linked lists • A linked list is a chain of nodes where each node stores the address of the next node Start 7 2 6 8 This symbol indicates a null pointer January 20, 2020 Cinda Heeren / Andy Roth / Geoffrey Tien 6
Linked list implementation Node class class Node { public: int data; Node* next; }; next points to another node, hence its type Node * • attributes / members of a particular node can be accessed using the ' . ' (dot) operator – or the ' -> ' (arrow) operator as a shorthand for pointer types • equivalent to dereferencing and using dot operator Node nd; Node* p = nd.next; Node* q = *((*p).next).next; nd.data = 5; (*p).data = 5; Node* r = q->next->next; January 20, 2020 Cinda Heeren / Andy Roth / Geoffrey Tien 7
Building a linked list Assume we have written a parameterized Node* a = new Node(7, null); constructor for the Node class a 7 January 20, 2020 Cinda Heeren / Andy Roth / Geoffrey Tien 8
Building a linked list Node* a = new Node(7, null); a->next = new Node(3, null); a 7 3 January 20, 2020 Cinda Heeren / Andy Roth / Geoffrey Tien 9
Traversing a linked list 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; a 7 3 p January 20, 2020 Cinda Heeren / Andy Roth / Geoffrey Tien 10
Linked list insertion • Insertion in a singly-linked list requires only updating the next node reference of the preceding position a … 15 19 16 22 28 p 17 b Important! Node* b = new Node(17, p->next); Be aware that sequential nodes are not guaranteed to be found in p->next = b; sequential memory locations! January 20, 2020 Cinda Heeren / Andy Roth / Geoffrey Tien 11
Linked list removal • Likewise, we can remove a node by updating the pointer of the preceding node – but remember to delete the removed node! a … 15 19 16 22 28 p b p->next = b->next; delete b; January 20, 2020 Cinda Heeren / Andy Roth / Geoffrey Tien 12
Some linked list variations class Node { class LinkedList { class LinkedList { public: private: private: int data; Node* head; Node* head; Node* next; int length; Node* tail; int length; Node(int d, Node* nd) { public: data = d; next = nd; LinkedList(); public: } ... LinkedList(); }; }; ... }; • Suppose we have a basic singly-linked list with a head pointer as defined above – 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
Singly-linked list with tail pointer Insertion at back of list head 1 2 3 4 6 7 tail 9 new • We can now perform insertion at the back of list in 𝑃 1 time! – 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
Doubly-linked list • Node definition contains an additional pointer – links to previous node in the list, allows traversal or access towards the front of the list class Node { public: int data; head Node* prev; 5 2 9 6 Node* next; // constructors, etc. }; • Provides access to the previous and next nodes from a single pointer (e.g. for insertion/removal) – but, requires more pointer management in programming January 20, 2020 Cinda Heeren / Andy Roth / Geoffrey Tien 15
Doubly-linked list insertion After some specified node 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; head 6 4 23 12 curr temp 7 January 20, 2020 Cinda Heeren / Andy Roth / Geoffrey Tien 16
Doubly-linked list removal At some specified node Node* curr; ... // move curr to the node to be removed curr->next->prev = curr->prev; curr->prev->next = curr->next; delete curr; curr = NULL; head 23 6 12 7 4 curr January 20, 2020 Cinda Heeren / Andy Roth / Geoffrey Tien 17
Circular linked lists Singly-linked version • The last node in the list points back to the first node – requires no change to the Node definition – circular property is maintained during operations head 12 15 7 • How to check when we reach the end in a traversal? – address of next is the same as the address of the front – but still must be careful to do NULL check on empty list! January 20, 2020 Cinda Heeren / Andy Roth / Geoffrey Tien 18
Circular singly-linked list Insertion at head • Insertion in the middle of a circular singly-linked list is no different from inserting into a NULL-terminated list – what about inserting at the head? – need to iterate a pointer to the last node in the list! Node* ptr, * newnode; ptr = head; while (ptr->next != head) ptr = ptr->next; newnode = new Node(); newnode->data = 4; newnode->next = head; ptr ptr->next = newnode; head = newnode; head 12 15 7 3 9 newnode 4 January 20, 2020 Cinda Heeren / Andy Roth / Geoffrey Tien 19
Circular doubly-linked list • The last node in the list points to the first node – and the first node points to the last node head 6 23 15 What is the time complexity of accessing the last element of a circular doubly-linked list? January 20, 2020 Cinda Heeren / Andy Roth / Geoffrey Tien 20
Readings for this lesson • Carrano & Henry – Background: 1.4, C1.1-C1.4 – C2.3, C2.5 (Pointers, dynamic arrays) – Chapter 4 (Linked lists) • Next class: – Carrano & Henry: Chapter 6 (ADT Stack) January 20, 2020 Cinda Heeren / Andy Roth / Geoffrey Tien 21
Recommend
More recommend