DATA STRUCTURES AND ALGORITHMS LINKED LISTS 1 LINKED DATA ITEMS 2 WHAT IS A LIST? A list is a collection of items: It can have an arbitrary length Objects / elements can be inserted or removed at arbitrary locations in the list A list can be traversed in order one item at a time 3 VARIATIONS OF LINKED LISTS Singly linked lists Circular linked lists Doubly linked lists Circular doubly linked list 4 LINKED LIST Minimal Requirements Locate the first element Given the location of any list element, find its successor Determine if at the end of the list 5 LINKED LIST TERMINOLOGIES Traversal of List Means to visit every element or node in the list beginning from first to last. Predecessor and Successor In the list of elements, for any location n, (n-1) is predecessor and (n+1) is successor In other words, for any location n in the list, the left element is predecessor and the right element is successor. Also, the first element does not have predecessor and the last element does not have successor. 6 LINKED LISTS A B C Head A linked list is a series of connected nodes Each node contains at least node A piece of data (any type) Pointer to the next node in the list Head: pointer to the first node The last node points to NULL A data pointer 7 LISTS – ANOTHER PERSPECTIVE A list is a linear collection of varying length of homogeneous components. Homogeneous: All components are of the same type. Linear: Components are ordered in a line (hence called Linear linked lists). 8 ARRAYS VS LISTS • Arrays are lists that have a fixed size in memory. • The programmer must keep track of the length of the array • No matter how many elements of the array are used in a program, the array has the same amount of allocated space. • Array elements are stored in successive memory locations. Also, order of elements stored in array is same logically and physically. 9 ARRAYS VS LISTS • A linked list takes up only as much space in memory as is needed for the length of the list. • The list expands or contracts as you add or delete elements. • In linked list the elements are not stored in successive memory location • Elements can be added to (or deleted from) either end, or added to (or deleted from)the middle of the list. 10 ARRAY VERSUS LINKED LISTS Linked lists are more complex to code and manage than arrays, but they have some distinct advantages. Dynamic: a linked list can easily grow and shrink in size. We don’t need to know how many nodes will be in the list. They are created in memory as needed. In contrast, the size of a C++ array is fixed at compilation time. Easy and fast insertions and deletions To insert or delete an element in an array, we need to copy to temporary variables to make room for new elements or close the gap caused by deleted elements. With a linked list, no need to move other nodes. Only need to reset some pointers. 11 An Array A Linked List 12 BASIC OPERATIONS OF LINKED LIST Linked List, a linear collection of data items, called nodes, where order is given y means of pointers. Elements: Each node is divided into two parts: Information Link ( pointing towards the next node) (Common) Operations of Linked List IsEmpty: determine whether or not the list is empty InsertNode: insert a new node at a particular position FindNode: find a node with a given value DeleteNode: delete a node with a given value DisplayList: print all the nodes in the list 13 AN INTEGER LINKED LIST First Node of List Last Node of List list 10 13 data 5 next 2 NULL 14 CREATING A LIST NODE struct Node { int data; Node *next; }; // data in node // Pointer to next node Node *p; p = new Node; p - > data = 10; p - > next = NULL; p 10 15 CREATING A LIST NODE class Node { public: int data; Node *next; }; To avoid get/set methods // data in node // Pointer to next node Node *p; p = new Node; p - > data = 10; p - > next = NULL; p 10 16 THE NULL POINTER NULL is a special pointer value that does not reference any memory cell. If a pointer is not currently in use, it should be set to NULL so that one can determine that it is not pointing to a valid address: int *p; p = NULL; 17 Singly Linked List 18 Basic Concepts AN INTEGER (SINGLY) LINKED LIST First Node of List Last Node of List list 10 13 data class Node { public: int data; Node *next; }; 5 next 2 NULL 19 Basic Concepts JOINING TWO NODES Node *p, *q; p = new Node; p - > data = 10; p - > next = NULL; q = new Node; q - > data = 6; q - > next = NULL; p - > next = q; p p 10 q 6 10 6 20 q Basic Concepts ACCESSING LIST DATA Node 1 p 10 Expression p p - > data p - > next p - > next - > data p - > next - > next Node 2 6 Value Pointer to first node (head) 10 Pointer to next node 6 NULL pointer 21 BASIC LINKED LIST OPERATIONS Traversing through the list Node Insertion Insertion at the beginning of the list Insertion at the end of the list Insertion in the middle of the list Node Deletion Deletion at the beginning of the list Deletion at the end of the list Deletion from the middle of the list 22 Traversing the list 23 TRAVERSING THE LIST ptr = first; while (ptr != null_value) { Process data part of node pointed to by ptr ptr = next part of node pointed to by ptr; } 24 first ptr = first; while (ptr != null_value) { Process data part of node pointed to by ptr; 9 17 22 26 34 9 17 22 26 34 22 26 34 ptr first ptr = next part of node pointed to by ptr; } ptr . . . first 9 17 ptr first 9 17 22 26 34 ptr 25 TRAVERSING THE LIST Node * currNode; currNode = head; while (currNode != NULL) { cout<< currNode->data; currNode = currNode->next; } 26 NODE INSERTION Insertion at the beginning of the list Insertion at the end of the list Insertion in the middle of the list 27 NODE INSERTION AT THE BEGINNING Steps: Create a node Set the node data values Connect the pointers head Initial list Step 1 Step 2 List after Step 3 head 48 93 17 142 // NODE INSERTION AT THE BEGINNING head Initial list Node *ptr; ptr = new Node; ptr - > data = 93; ptr - > next = head; head = ptr; head Rearrange: head 93 48 17 ptr ptr head 93 142 // NODE INSERTION AT THE END Steps: Create a Node Set the node data values Connect the pointers Initial list Step 1 List after Step 3 head 48 Step 2 17 142 // NODE INSERTION AT THE END Initial list head 48 17 Need a pointer at the last node Node * ptr; ptr = head; while (ptr->next != NULL) { ptr = ptr->next; } 142 ptr // NODE INSERTION AT THE END Initial list head 48 17 142 ptr Node * p; p = new Node; p -> data = 150; p -> next = NULL; 150 p // // NODE INSERTION AT THE END Node * p; p = new Node; p -> data = 150; p -> next = NULL; ptr -> next = p; head 48 ptr 17 142 150 p // NODE INSERTION AT ARBITRARY POSITION Steps: Create a Node Set the node data values Break pointer connection Re-connect the pointers Step 3 Step 4 Step 1 Step 2 NODE INSERTION AT ARBITRARY POSITION Steps: Create a Node Set the node data values Break pointer connection Re-connect the pointers Need a pointer on the node after which a new node is to be Inserted. For instance, if new node is to be inserted after the node having value ‘17’, we need a pointer at this node ptr How to get pointer on desired node? NODE INSERTION AT ARBITRARY POSITION Suppose we want to insert a node after the node having value ‘x’: Node * ptr; ptr = head; while (ptr->data != x) { ptr = ptr->next; } ptr NODE INSERTION AT ARBITRARY POSITION Node * p; p = new Node; p -> data = 100; p -> next = NULL; Node * ptr; ptr = head; while (ptr->data != x) { ptr = ptr->next; } ptr 150 p // NODE INSERTION AT ARBITRARY POSITION Node * p; p = new Node; p -> data = 100; p -> next = NULL; p -> next = ptr -> next; ptr -> next = p; Node * ptr; ptr = head; while (ptr->data != x) { ptr = ptr->next; } ptr 150 p NODE DELETION Deleting from the beginning of the list Deleting from the end of the list Deleting from the middle of the list DELETING FROM THE BEGINNING Steps: Break the pointer connection Re-connect the nodes Delete the node head 6 4 17 42 6 4 17 42 head head 4 17 42 DELETING FROM THE BEGINNING head ptr head head ptr head 6 4 6 42 17 4 4 17 Node * ptr; ptr = head; head = head ->next; delete ptr; 42 17 42 DELETING FROM THE END Steps: Break the pointer connection Set previous node pointer to NULL Delete the node head 6 4 17 42 head 6 4 17 42 head 6 4 17 DELETING FROM THE END We need a pointer one node before the node to be deleted head 6 4 Node * ptr; Node * predPtr; ptr = head; predPtr = NULL; while (ptr->next != NULL) { predPtr = ptr; ptr = ptr->next; } 17 42 predPtr ptr DELETING FROM THE END 6 head head 17 42 predPtr ptr 17 42 4 6 4 predPtr head 6 4 ptr 42 17 ptr predPtr head 6 4 17 predPtr -> next = NULL; delete ptr; DELETING FROM AN ARBITRARY POSITION Steps: Set previous Node pointer to next node Break Node pointer connection Delete the node head head head 4 17 42 4 17 42 4 42 DELETING FROM AN ARBITRARY POSITION We need a pointer on the node to be deleted (as well a pointer to one node before the node to be deleted) head 4 predPtr Node * ptr; Node * predPtr; ptr = head; predPtr = NULL; while (ptr->data != x) { predPtr = ptr; ptr = ptr->next; } 17 42 ptr Given the value of the node to be deleted, assume this to be variable ‘x’ Keep moving a pointer until the required node is reached DELETING FROM AN ARBITRARY POSITION head head head 4 17 predPtr ptr 4 17 predPtr ptr 4 17 predPtr ptr 42 42 42 predPtr -> next = ptr -> next; delete ptr; PROS AND CONS OF LINKED LISTS • Access any item as long as external link to first item maintained • Insert new item without shifting • Delete existing item without shifting • Can expand/contract as necessary • Overhead of links: • No longer have direct access to each element of the list • We must go through first element, and then second, and then third, etc. 48