UNIT 3a - Linked List
UNIT 3a - Linked List
Session: 2025
Course Coordinator
Dr. Madhu Sharma
Assistant Professor, School of Computing
Course Instructor
Dr. Madhu Sharma
Assistant Professor, School of Computing
DATA STRUCTURE
Unit 3: Linked Lists and Trees ( 8 L)
• Linked Lists:
• Introduction to Dynamic Memory Allocation,
• Representation and Implementation of Single, Double, and Circular Linked Lists
• Operations on Linked List: Insert, Delete, Traverse etc.
• Applications of Linked List,
• Linked List representation of Stack and Queue.
• Trees:
• Basic Tree terminologies,
• Types of Trees:
• Binary Tree, Binary Search Tree (BST), AVL Tree, B-Tree, and Heap.
new_node=(Node*)malloc(sizeof(Node));
if(new_node==NULL){
printf("unable to allocate memory");
exit(0);
}
else{
new_node->data=item;
new_node->next=NULL;
new_node->next=head;
head=new_node;
}
return head;
}
• Time complexity = O(1).
Linked List
/* Given a node prev_node, insert a new node after the given
• Add a node after a given node: (5 steps process) ) prev_node */
void insertAfter(struct Node* prev_node, int new_data)
{
/*1. check if the given prev_node is NULL */
if (prev_node == NULL) {
printf("the given previous node cannot be NULL");
return;
}
new_node->data=item;
new_node->next=NULL;
tmp=head;
while(tmp->next!=NULL){
tmp=tmp->next;
}
tmp->next=new_node;
}
return head;
}
}
else{
ptr1=head;
while(ptr1->next->next!=NULL){
ptr1=ptr1->next;
}
ptr=ptr1->next;
ptr1->next=NULL;
printf("\ndeleted elemnet is->%d",ptr->data);
free(ptr);
}
return head;
}
Linked List
at the middle
Doubly Linked List
A Doubly Linked List (DLL) contains an extra pointer, typically called previous pointer, together with next pointer and data
which are there in singly linked list.
/* Node of a doubly linked list */
struct Node {
int data;
struct Node* next; // Pointer to next node in DLL
struct Node* prev; // Pointer to previous node in
DLL
};
Doubly Linked List
Advantages over singly linked list
A DLL can be traversed in both forward and backward direction.
The delete operation in DLL is more efficient if pointer to the node to be deleted is given.
We can quickly insert a new node before a given node.
In singly linked list, to delete a node, pointer to the previous node is needed. To get this previous node, sometimes the
list is traversed. In DLL, we can get the previous node using previous pointer.
Disadvantages over singly linked list
Every node of DLL Require extra space for an previous pointer. It is possible to implement DLL with single pointer
though (See this and this).
All operations require an extra pointer previous to be maintained. For example, in insertion, we need to modify
previous pointers together with next pointers. For example in following functions for insertions at different positions, we
need 1 or 2 extra steps to set previous pointer.
Insertion in DLL
Insertion in linked list can be done in three ways:
At the front of the DLL
After a given node.
At the end of the DLL
Insertion in DLL
Insertion in linked list can be done in three ways:
At the front of the DLL
Insertion in DLL
Insertion in linked list can be done in three ways:
At the end of the DLL
Insertion in DLL
Insertion in linked list can be done in three ways:
After a given node.
Insertion in DLL
Node* ins_first(Node* head, int item){
• Add a node at the front: (A 5 steps process) Node *new_node;
new_node=(Node*)malloc(sizeof(Node));
if(new_node==NULL){
printf("unable to allocate");
exit(0);
}
else{
new_node->data=item;
new_node->next=NULL;
new_node->prev=NULL;
new_node->next=head;
head->prev=new_node
head=new_node;
}
return head;
}
Insertion in DLL
Node *ins_after(Node *head, int item, int key){
• Add a node after a given node : Node *new_node,*tmp;
new_node=(Node*)malloc(sizeof(Node));
if(new_node==NULL){
printf("unable to allocate memory");
exit(0);
}
else{
new_node->data=item;
new_node->next=NULL;
new_node->prev=NULL;
tmp=head;
while(tmp->data!=key){
tmp=tmp->next;
}
new_node->next=tmp->next;
tmp->next->prev=new_node;
tmp->next=new_node;
new_node->prev=tmp;
}
return head;
}
Insertion in DLL
Node* ins_last(Node* head,int item){
Node *new_node,*tmp;
• Add a node at the end: new_node=(Node*)malloc(sizeof(Node));
if(new_node==NULL){
printf("unable to allocate memory");
exit(0);
}
else{
new_node->data=item;
new_node->next=NULL;
new_node->prev=NULL;
tmp=head;
while(tmp->next!=NULL){
tmp=tmp->next;
}
tmp->next=new_node;
new_node->prev=tmp;
}
return head;
}
Insertion in DLL
• Add a node before a given node:
Node *ins_before(Node *head, int item, int key){
Node *new_node,*tmp;
new_node=(Node*)malloc(sizeof(Node));
if(new_node==NULL){
printf("unable to allocate");
exit(0);
}
else{
new_node->data=item;
new_node->next=NULL;
new_node->prev=NULL;
tmp=head;
while(tmp->data!=key){
tmp=tmp->next;
}
new_node->next=tmp;
tmp->prev->next=new_node;
new_node->prev=tmp->prev;
tmp->prev=new_node;
}
return head;
Deletion in DLL
The deletion of a node in a doubly linked list can be divided into three main categories:
Deletion at beginning
Deletion in DLL
The deletion of a node in a doubly linked list can be divided into three main categories:
At the end
Deletion in DLL
The deletion of a node in a doubly linked list can be divided into three main categories:
Algorithm
• STEP 1: IF HEAD = NULL
WRITE UNDERFLOW
GOTO STEP 6
STEP 2: SET PTR = HEAD
• STEP 3: SET HEAD = HEAD → NEXT
• STEP 4: SET HEAD → PREV = NULL
• STEP 5: FREE PTR
• STEP 6: EXIT
Deletion in DLL
• After the specified node:
• In order to delete the node after the specified data
• Step 1: IF HEAD = NULL
Write UNDERFLOW
Go to Step 9
[END OF IF]
• Step 2: SET TEMP = HEAD
• Step 3: Repeat Step 4 while TEMP -> DATA != ITEM
• Step 4: SET TEMP = TEMP -> NEXT
[END OF LOOP]
• Step 5: SET PTR = TEMP -> NEXT
• Step 6: SET TEMP -> NEXT = PTR -> NEXT
• Step 7: SET PTR -> NEXT -> PREV = TEMP
• Step 8: FREE PTR
• Step 9: EXIT
Deletion in DLL
• At the End:
Step 1: IF HEAD = NULL
Write UNDERFLOW
Go to Step 7
[END OF IF]
Step 2: SET TEMP = HEAD
Step 3: REPEAT STEP 4 WHILE TEMP->NEXT != NULL
Step 4: SET TEMP = TEMP->NEXT
[END OF LOOP]
Step 5: SET TEMP ->PREV-> NEXT = NULL
Step 6: FREE TEMP
Step 7: EXIT
Circular Linked List
Circular linked list is a linked list where all nodes are connected to form a circle. There is no NULL at the end. A circular
linked list can be a singly circular linked list or doubly circular linked list.
Circular Linked List
Advantages of Circular Linked Lists:
Can traverse the whole list by heading from any point. We just need to stop when the first visited node is visited again.
Circular lists are useful in applications to repeatedly go around the list.
For example, when multiple applications are running on a PC, it is common for the operating system to put the
running applications on a list and then to cycle through them, giving each of them a slice of time to execute, and
then making them wait while the CPU is given to another application. It is convenient for the operating system to
use a circular list so that when it reaches the end of the list it can cycle around to the front of the list.
Circular Doubly Linked Lists are used for implementation of advanced data structures like Fibonacci Heap.
Circular Linked List
Implementation:
To implement a circular singly linked list, we take an external pointer that points to the last node of the list. If we have
a pointer last pointing to the last node, then last -> next will point to the first node.
Why have we taken a pointer that points to the last node instead of first node ?
For insertion of node in the beginning we need traverse the whole list.
Also, for insertion at the end, the whole list has to be traversed.
If instead of head pointer we take a pointer to the last node then in both the cases there won’t be any need to traverse
the whole list. So insertion in the beginning or at the end takes constant time irrespective of the length of the list.
Circular Linked List
Algorithm to insert a new node at the beginning
Circular Linked List
Algorithm to insert a new node at the end
Insertion in CLL
A node can be added in three ways:
Insertion in an empty list
Insertion at the beginning of the list
Insertion at the end of the list
Insertion in CLL
struct Node *addToEmpty(struct Node *last, int data)
{
// This function is only for empty list
if (last != NULL)
return last;
// Creating a node dynamically.
struct Node *temp =
(struct Node*)malloc(sizeof(struct Node));
// Assigning the data.
temp -> data = data;
last = temp;
// Note : list was empty. We link single node to itself.
temp -> next = last;
return last;
}
Insertion in CLL
Insertion at the beginning of the list
1. Create a node, say T.
2. Make T -> next = last -> next.
3. last -> next = T.
deleteAtBeginning(last):
if last is NULL:
return // List is empty
if last->next == last:
free(last)
last = NULL
else:
temp = last->next
last->next = temp->next
free(temp)
Deletion in CLL
Deletion in last
deleteAtEnd(last):
if last is NULL:
return // List is empty
if last->next == last:
free(last)
last = NULL
else:
temp = last->next
while temp->next != last:
temp = temp->next
temp->next = last->next
free(last)
last = temp
Deletion After a Given Node:
Deletion in CLL
deleteAfterNode(last, key):
if last is NULL:
return // List is empty
current = last->next
while current != last:
if current->data == key:
temp = current->next
current->next = temp->next
free(temp)
return
current = current->next
// If key is not found
if current->data == key:
temp = current->next
current->next = temp->next
free(temp)
Deletion in CLL
A node can be deleted in three ways when HEAD pointer is given:
First position.
Last Position
Particular node(same as singly linked list)
Deletion in CLL
Deletion at the beginning of the list
Step 1: IF HEAD = NULL
Write UNDERFLOW
Go to Step 8
[END OF IF]
Step 2: SET PTR = HEAD
Step 3: Repeat Step 4 while PTR → NEXT !=
HEAD
Step 4: SET PTR = PTR → NEXT
[END OF LOOP]
Step 5: SET PTR → NEXT = HEAD → NEXT
Step 6: FREE HEAD
Step 7: SET HEAD = PTR → NEXT
Step 8: EXIT
Deletion in CLL
Deletion in last