Linked List
Linked List
1
Introduction to Linked Lists
header
A B C NULL
3
Linked List
• Few salient features
• There is a pointer (called header) points the first element (also called node)
• Successive nodes are connected by pointers.
• Last element points to NULL.
• It can grow or shrink in size during execution of a program.
• It can be made just as long as required.
• It does not waste memory space, consume exactly what it needs.
4
Arrays versus Linked Lists
5
Array: Contagious Storage
arrayName
0 10
1 15
2 20
3 22
4 25
5 30
6 35
7 40
8 45
9 50
6
Array versus Linked Lists
• In arrays
• elements are stored in a contagious memory locations
• Arrays are static data structure unless we use dynamic memory
allocation
7
Linked List: Non-Contagious Storage
h a i e c g
a
15 10 15 20 22 25 30
b f k b d
45
c
25 35 40 45 50
d
50
e
22 h
f 10 a 15 i 20 e 22 c 25 g 30 f
35
g
30
h 35 k 40 b 45 d 50
10
i
20 h
j
10 15 20 22 25 30
k
40
35 40 45 50
CS 10001 : Programming and Data Stru 8 Lecture #05: © DSamanta
ctures
Array versus Linked Lists
• In Linked lists
• adjacency between any two elements are maintained by means of links
or pointers
struct node
node
{
int data; /* Data */ Data
struct node *next; /* pointer*/ next
} ;
Note:
Such structures which contain a member field pointing to the same structure type are
called self-referential structures.
11
Types of Lists: Single Linked List
Depending on the way in which the links are used to maintain
adjacency, several different types of linked lists are possible.
head
A B C NULL
12
Types of Lists: Double Linked List
Double linked list
• Pointers exist between adjacent nodes in both directions.
• The list can be traversed either forward or backward.
• Usually two pointers are maintained to keep track of the list, head and
tail.
head tail
A B C
13
Defining a Node of a Double Linked List
Each node of doubly linked list (DLL) consists of three fields:
• Item (or) Data
• Pointer of the next node in DLL
• Pointer of the previous node in DLL
node
Data
prev next
14
Double Linked List
• Doubly linked list is a collection of nodes linked together in a sequential way.
• Doubly linked list is almost similar to singly linked list except it contains two
address or reference fields, where one of the address field contains reference of
the next node and other contains reference of the previous node.
• First and last node of a linked list contains a terminator generally a NULL
value, that determines the start and end of the list.
• Doubly linked list is sometimes also referred as bi-directional linked list since it
allows traversal of nodes in both direction.
• Since doubly linked list allows the traversal of nodes in both direction, we can
keep track of both first and last nodes.
15
Double versus Single Linked List
16
Types of Lists: Circular Linked List
A B C
17
Circular Linked List
• A circular linked list is basically a linear linked list that may be single- or
double-linked.
• The only difference is that there is no any NULL value terminating the list.
• In fact in the list every node points to the next node and last node points to the
first node, thus forming a circle. Since it forms a circle with no end to stop it is
called as circular linked list.
• In circular linked list there can be no starting or ending node, whole node can be
traversed from any node.
• In order to traverse the circular linked list, only once we need to traverse entire
list until the starting node is not traversed again.
• A circular linked list can be implemented using both singly linked list and
doubly linked list.
18
Example 1: Creating a Single Linked List
Linked list to store and print roll number, name and age of 3 students.
#include <stdio.h>
struct stud
{
int roll;
char name[30];
int age;
struct stud *next;
};
main()
{
struct stud n1, n2, n3;
struct stud *p;
scanf (“%d %s %d”, &n1.roll, n1.name, &n1.age);
scanf (“%d %s %d”, &n2.roll,n2.name, &n2.age);
scanf (“%d %s %d”, &n3.roll,n3.name, &n3.age);
19
Example 1: Creating a Single Linked List
n1.next = &n2 ;
n2.next = &n3 ;
n3.next = NULL ;
/* Now traverse the list and print the elements */
p = &n1 ; /* point to 1st element */
while (p != NULL)
{
printf (“\n %d %s %d”, p->roll, p->name, p->age);
p = p->next;
}
}
20
Example 1: Illustration
The structure:
struct stud
{
int roll;
char name[30];
int age;
struct stud *next;
};
Also assume the list with three nodes n1, n2 and n3 for 3 students.
21
Example 1: Illustration
To create the links between nodes, it is written as:
n1.next = &n2 ;
n2.next = &n3 ;
n3.next = NULL ; /* No more nodes follow */
rol
l
nam
eag
e
nex NULL
t n1 n2 n3
22
Example 2: Creating a Single Linked List
C-program to store 10 values on a linked list reading the data from keyboard.
#include <stdio.h>
#include <stdlib.h>
struct node {
int data; //Data part
struct node *next; //Address part
}*header;
int main()
{
int n;
printf("Enter the total number of nodes: ");
scanf("%d", &n);
createList(n);
return 0;
}
23
Example 2: Creating a Single Linked List
void createList(int n)
{
struct node *newNode, *temp;
int data, i;
24
Example 2: Creating a Single Linked List
for(i=2; i<= n; i++)
{
/* A newNode is created by allocating memory */
newNode = (struct node *)malloc(sizeof(struct node));
if(newNode == NULL)
{
printf("Unable to allocate memory.");
break;
}
else
{
printf("Enter the data of node %d: ", i);
scanf("%d", &data);
25
Example 2: Illustration
• To start with, we have to create a node (the first node), and make header point to
it.
It creates a single node. For example, if the data entered is 100 then the list
look like
header
100 NULL
26
Creating a single linked list
If we need n number of nodes in the linked list:
• Allocate n newNodes, one by one.
• Read in the data for the newNodes.
• Modify the links of the newNodes so that the chain is formed.
It creates n number of nodes . For e.g. if the data entered is 200, 50, 30 then
the list look like
hea
d 10 20 50 30 NULL
0 0
27
Example 3: Creating a Single Linked List
C-program to copy an array to a single linked list.
#include <stdio.h>
#include <stdlib.h>
struct node {
int data; //Data part
struct node *next; //Address part
};
int main()
{
struct node *header, *newNode, *temp;
int data, i, n, a[100];
printf("Enter the total number of data: ");
scanf("%d", &n);
// Write code here to initialize the array a with n elements //
...
28
Example 2: Creating a Single Linked List
/* A node is created by allocating memory to a structure */
newNode = (struct node *)malloc(sizeof(struct node));
29
Example 2: Creating a Single Linked List
for(i = 1; i <= n; i++)
{
/* A newNode is created by allocating memory */
newNode = (struct node *)malloc(sizeof(struct node));
if(newNode == NULL)
{
printf("Unable to allocate memory.");
break;
}
else
{
newNode->data = a[i]; //Links the data field of newNode with a[i]
newNode->next = NULL; //Links the address field of newNode with NULL
30
Operations on Linked Lists
31
Operations on single linked list
• Traversing a list
• Printing, finding minimum, etc.
33
Single Linked List: Traversing
Once the linked list has been constructed and header points to the
first node of the list,
• Follow the pointers.
• Display the contents of the nodes as they are traversed.
• Stop when the next pointer points to NULL.
35
Insertion in a Linked List
36
Single Linked List: Insertion
Insertion steps:
• Create a new node
• Start from the header node
• Manage links to
• Insert at front
• Insert at end
• Insert at any position
37
Insertion at Front
38
Insertion at Front
Step 2: Link the newly created node with the head node, i.e. the newNode will now
point to head node.
Step 3: Make the new node as the head node, i.e. now head node will point to newNode.
39
Insertion at front
/*Create a new node and insert at the beginning of the linked list.*/
if(newNode == NULL)
{
printf("Unable to allocate memory.");
}
else
{
newNode->data = data; //Links the data part
newNode->next = head; //Links the address part
40
Single Linked List: Insertion at End
Step 2: Traverse to the last node of the linked list and connect the last node of the list with
the new node, i.e. last node will now point to new node. (lastNode->next =
newNode).
41
Insertion at End
/* Create a new node and insert at the end of the linked list. */
void insertNodeAtEnd(int data)
{
struct node *newNode, *temp;
newNode = (struct node*)malloc(sizeof(struct node));
if(newNode == NULL)
{
printf("Unable to allocate memory.");
}
else
{
newNode->data = data; //Links the data part
newNode->next = NULL;
temp = head;
42
Single Linked List: Insertion at any Position
Steps to insert node at any position of Singly Linked List
Step 1: Create a new node.
Step 2: Traverse to the n-1th position of the linked list and connect the new node with the
n+1th node. (newNode->next = temp->next) where temp is the n-1th node.
43
Single Linked List: Insertion at any position
Step 3: Now at last connect the n-1th node with the new node i.e. the n-1th node will now
point to new node. (temp->next = newNode) where temp is the n-1th node.
44
Insertion at any Position
if(newNode == NULL)
{
printf("Unable to allocate memory.");
}
else
{
newNode->data = data; //Links the data part
newNode->next = NULL;
temp = head;
45
Insertion at any Position
if(temp == NULL)
break;
}
if(temp != NULL)
{
/* Links the address part of new node */
newNode->next = temp->next;
46
Double Linked List: Insertion at any Position
Steps to insert a new node at nth position in a Doubly linked list.
Step 1: Traverse to N-1 node in the list, where N is the position to insert. Say temp now
points to N-1th node.
Step 2: Create a newNode that is to be inserted and assign some data to its data field.
47
Doubly Linked List: Insertion at any Position
Step 3: Connect the next address field of newNode with the node pointed by next address
field of temp node.
Step 4: Connect the previous address field of newNode with the temp node.
48
Doubly Linked List: Insertion at any Position
Step 5: Check if temp.next is not NULL then, connect the previous address field of node
pointed by temp.next to newNode.
49
Doubly Linked List: Insertion at any Position
Step 7: Final doubly linked list looks like
50
Doubly Linked List: Insertion at any Position
#include <stdio.h>
#include <stdlib.h>
int main()
{
int n, data;
head = NULL;
last = NULL;
51
Doubly Linked List: Insertion at any Position
void createList(int n)
{
int i, data;
struct node *newNode;
if(n >= 1){ /* Creates and links the head node */
head = (struct node *)malloc(sizeof(struct node));
printf("Enter data of 1 node: ");
scanf("%d", &data);
head->data = data;
head->prev = NULL;
head->next = NULL;
last = head;
for(i=2; i<=n; i++){ /* Creates and links rest of the n-1 nodes */
newNode = (struct node *)malloc(sizeof(struct node));
printf("Enter data of %d node: ", i);
scanf("%d", &data);
newNode->data = data;
newNode->prev = last; //Links new node with the previous node
newNode->next = NULL;
52
Doubly Linked List: Insertion at any Position
void insert_position(int data, int position)
{
struct node * newNode, *temp;
if(head == NULL){
printf("Error, List is empty!\n");
}
else{
temp = head;
if(temp!=NULL){
newNode = (struct node *)malloc(sizeof(struct node));
newNode->data = data;
newNode->next = temp->next; //Connects new node with n+1th node
newNode->prev = temp; //Connects new node with n-1th node
if(temp->next != NULL)
{
temp->next->prev = newNode; /* Connects n+1th node with new node */
}
temp->next = newNode; /* Connects n-1th node with new node */
printf("NODE INSERTED SUCCESSFULLY AT %d POSITION\n", position);
}
else{
printf("Error, Invalid position\n");
}
}
}
53
Doubly Linked List: Insertion at any Position
void displayList()
{
struct node * temp;
int n = 1;
if(head == NULL)
{
printf("List is empty.\n");
}
else
{
temp = head;
printf("DATA IN THE LIST:\n");
while(temp != NULL)
{
printf("DATA of %d node = %d\n", n, temp->data);
n++;
54
Few Exercises to Try Out
For doubly linked list write a function to:
• Insert a node at front of the list and at end of the list.
insert_front(data);
insert_end(data);
55
Deletion from a Linked List
56
Single Linked List: Deletion
Deletion steps
• Start from the header node
• Manage links to
• Delete at front
• Delete at end
• Delete at any position
• freeingup the node as free space.
57
Free Memory after Deletion
• Do not forget to free() memory location dynamically allocated
for a node after deletion of that node.
58
Single Linked List: Deletion at Front
Steps to delete first node of Singly Linked List
Step 1: Copy the address of first node i.e. head node to some temp variable say toDelete.
Step 2: Move the head to the second node of the linked list (head = head->next).
59
Single linked list: Deletion at front
Step 3: Disconnect the connection of first node to second node.
60
Deletion at Front
if(head == NULL)
{
printf("List is already empty.");
}
else
{
toDelete = head;
head = head->next;
61
Single linked list: Deletion at End
Steps to delete last node of a Singly Linked List
Step 1: Traverse to the last node of the linked list keeping track of the second last node in
some temp variable say secondLastNode.
Step 2: If the last node is the head node then make the head node as NULL else disconnect
the second last node with the last node i.e. secondLastNode->next = NULL
62
Single linked list: Deletion at End
Step 3: Free the memory occupied by the last node.
63
Deletion at End
64
Single Linked List: Deletion at any Position
Steps to delete a node at any position of Singly Linked List
Step 1: Traverse to the nth node of the singly linked list and also keep reference of n-1 th node
in some temp variable say prevNode.
Step 2: Reconnect n-1th node with the n+1th node i.e. prevNode->next = toDelete->next
(Where prevNode is n-1th node and toDelete node is the nth node and toDelete->next is the n+1th
node).
65
Single Linked List: Deletion at any Position
Step 3: Free the memory occupied by the nth node i.e. toDelete node.
66
Deletion at any Position
if(toDelete == NULL)
break;
}
67
Deletion at any Position
if(toDelete != NULL)
{
if(toDelete == head)
head = head->next;
prevNode->next = toDelete->next;
toDelete->next = NULL;
68
Comparing Two Linked Lists
69
Single Linked List: Comparing two Lists
Comparing two linked list includes
• Identifying whether the given two linked list are identical.
• Two Linked Lists are identical when they have same data and
arrangement of data is also same.
70
Comparing two Linked Lists
/* Return true if linked lists a and b are identical, otherwise false */
bool areIdentical(struct node *a, struct node *b)
{
while (a != NULL && b != NULL)
{
if (a->data != b->data)
return false;
/* If we reach here, then a and b are not NULL and their data is same, so
move to next nodes in both lists */
a = a->next;
b = b->next;
}
//If linked lists are identical, then 'a' and 'b' must be NULL at this point.
return (a == NULL && b == NULL);
}
int main()
{
struct node *a, *b;
a = createList(5); // e.g: a: 5->4->3->2->1
b = createList(5); // e.g: b: 5->4->3->2->1
areIdentical(a, b)? printf("Identical"): printf("Not identical");
return 0;
}
71
Few Exercises to Try Out
Write a function to:
• Concatenate or merge two given list into one big list.
node *concatenate(node *a, node *b);
• Compare two given list with same data but different arrangement.
e.g: a: 5->4->3->2->1
b: 1->2->3->4->5
• Count the number of nodes in the given list using iterative method
and recursive method.
72
Ordering Linked List
73
Single Linked List: Reversing
Reversing a list can be performed in two ways:
• Iterative method
• Recursive method
74
Reversing a List
Step 2: Now, disconnect the first node from others. We will make sure that it points to none.
As this node is going to be our last node. Perform operation prevNode->next = NULL.
Step 3: Move the head node to its next node i.e. head = head->next.
75
Reversing a List
Step 4: Now, re-connect the current node to its previous node
i.e. curNode->next = prevNode;
Step 5: Point the previous node to current node and current node to head node. Means they
should now point to prevNode = curNode; and curNode = head.
76
Reversing a List
Step 6: Repeat steps 3-5 till head pointer becomes NULL.
Step 7: Now, after all nodes has been re-connected in the reverse order. Make the last node
as the first node. Means the head pointer should point to prevNode pointer.
• Perform head = prevNode; And finally you end up with a reversed linked list of
its original.
77
Reversing a List: Iterative Method
void reverseList()
{
struct node *prevNode, *curNode;
if(head != NULL)
{
prevNode = head;
curNode = head->next;
head = head->next;
while(head != NULL)
{
head = head->next;
curNode->next = prevNode;
prevNode = curNode;
curNode = head;
}
78
Reversing a List: Recursive Method
int main()
{
int n = 10;
createList(n); // creates 10 nodes in the linked list
Recursive_Reverse(head);
return 0;
}
79
Single Linked List: Sorting
The linked list can be ordered using any of the following sorting
algorithms:
• Insertion sort
• Selection sort
• Merge sort
• Quick sort
• Bubble sort, etc.
80
Sorting a List using Insertion Sort
// function to sort a singly linked list using insertion sort
void insertionSort(struct node **head_ref)
{
// Initialize sorted linked list
struct node *sorted = NULL;
// Traverse the given linked list and insert every node to be sorted
struct node *current = *head_ref;
while (current != NULL)
{
struct node *next = current->next;
81
Sorting a List using Insertion Sort
/* function to insert a new_node in a list.*/
void sortedInsert(struct node** head_ref, struct node* new_node)
{
struct node* current;
82
Sorting a List using Insertion Sort
int main()
{
int n=5;
createList(n);
insertionSort(&head);
printf("\nData after sorting the list \n");
displayList();
return 0;
}
Output:
Enter the data of node 1: 6
84
Circular linked list:
Advantages of a Circular linked list
• Entire list can be traversed from any node.
• Circular lists are the required data structure when we want a list to be accessed
in a circle or loop.
• Despite of being singly circular linked list we can easily traverse to its previous
node, which is not possible in singly linked list.
85
Operations on circular linked list
• Creation of list
• Traversal of list
• Insertion of node
• At the beginning of list
• At any position in the list
• Deletion of node
• Deletion of first node
• Deletion of node from middle of the list
• Deletion of last node
• Counting total number of nodes
• Reversing of list
86
Creation and Traversal of a Circular List
#include <stdio.h>
#include <stdlib.h>
struct node {
int data;
struct node * next;
}*head;
int main()
{
int n, data;
head = NULL;
return 0;
}
87
Circular Linked List: Creation of List
void createList(int n)
{
int i, data;
struct node *prevNode, *newNode;
if(n >= 1){ /* Creates and links the head node */
head = (struct node *)malloc(sizeof(struct node));
head->data = data;
head->next = NULL;
prevNode = head;
for(i=2; i<=n; i++){ /* Creates and links rest of the n-1 nodes */
newNode = (struct node *)malloc(sizeof(struct node));
newNode->data = data;
newNode->next = NULL;
prevNode->next = newNode; //Links the previous node with newly created node
prevNode = newNode; //Moves the previous node ahead
}
prevNode->next = head; //Links the last node with first node
printf("\nCIRCULAR LINKED LIST CREATED SUCCESSFULLY\n");
}
}
88
Circular Linked List: Traversal of List
void displayList()
{
struct node *current;
int n = 1;
if(head == NULL)
{
printf("List is empty.\n");
}
else
{
current = head;
printf("DATA IN THE LIST:\n");
do {
printf("Data %d = %d\n", n, current->data);
current = current->next;
n++;
}while(current != head);
}
}
89
Few Exercises to Try Out
For circular linked list write a function to:
• Insert a node at any position of the list and delete from the
beginning of the list.
insert_position(data,position);
delete_front();
90