Data Structure
and Algorithm
4330704
Rutvi S. Sheth
Unit-4 Linked List
CO3: Apply basic operations on the linked list data structure.
4.1 Pointers Revision
• Pointer: A pointer is a variable which contains an address of
another variable in memory.
• It is declared by * indicator..
• We can create a pointer variable in C using following syntax:
• Declaration: int *ptr;
4.2 Revision of Structures
• Structures hold data that belong together.
• Examples:
• Student record: student id, name, major, gender, start year, …
• Bank account: account number, name, currency, balance, …
• Address book: name, address, telephone number, …
• In database applications, structures are called records.
4.2 Revision of Structures
• Definition of a structure:
struct <struct-type>{
<type> <identifier_list>;
<type> <identifier_list>;
...
};
• Example:
struct Date {
int day;
int month;
int year
};
4.3 Revision of Structure using
•
pointer
Pointers are symbolic representation of addresses.
• Pointers enable programs to simulate call-by reference and to
create and manipulate dynamic data structures.
• Referencing a value through a pointer is called indirection.
• The * is called indirection operator.
4.4 Dynamic Memory Allocation
• In the Dynamic memory allocation , the memory is allocated to a variable or program
at the run Time.
• The only way to access this dynamically allocated memory is through pointer.
• Types of dynamic memory allocation:
1. Malloc ( )
• Allocates a specified number of bytes of memory.
• Does not initialize the memory.
• Syntax: void* malloc(size_t size);
2. Calloc( )
• Allocates memory for an array of elements, initializing them to zero.
• Syntax: void* calloc(size_t num, size_t size);
3. Realloc( )
4. Free ( )
4.4 Dynamic Memory Allocation
3. Realloc( )
• Resizes previously allocated memory.
• Can move the memory block to a new location if needed.
• Syntax: void* realloc(void* ptr, size_t size);
4. Free ( )
• Frees previously allocated memory.
• Syntax: void free(void* ptr);
4.4 Dynamic Memory Allocation
#include <stdio.h> // Print the entered integers
#include <stdlib.h> printf("You entered: ");
int main() { for (i = 0; i < n; i++)
int *arr;
{
int n, i;
printf("Enter the number of printf("%d ", arr[i]);
elements: "); }
scanf("%d", &n); printf("\n");
arr = (int *)malloc(n * sizeof(int)); // Free the allocated memory
printf("Enter %d integers:\n", n); free(arr);
for (i = 0; i < n; i++) printf("Memory successfully
{ freed.\n"); return 0;
scanf("%d", &arr[i]);
}
}
4.5 Linked List Representation
• A singly linked list is to expand each node to contain a link or pointer to
the next node. This is also called as a one way chain.
• First contain the address of the first node of the lists.
• Each node in the list consist of two parts::
1. Information(INFO)
2. Address or printer to next node (LINK).
4.6 Types of Linked List
Singly Linked List
Singly Circular Linked List
Doubly Linked List
Doubly Circular Linked List
Ordered Linked List
Singly Linked List
• Singly Linked List is a collection of variable number of nodes
in which each node consists of two parts. First part contains
a value of the node and second part contains an address of
the next node
• Consider Following example in which Singly Linked List
consist of four nodes.
• Each node having INFO part and LINK part.
• INFO part contains value of the node.
• LINK part contains address of the next node in the linked list.
Doubly Linked List
• Doubly Linked List is a collection of variable number of nodes
in which each node consists of three parts. First part contains
an address of previous node, second part contains a value of
the node and third part contains an address of the next node.
• INFO part contains value of the node.
• LPTR part contains an address of the previous node in the
linked list. If previous node is not present then LPTR part
contains NULL value. Thus LPTR part of the first node always
contains NULL value.
• RPTR part contains an address of the next node. RPTR part of
the last node always contains NULL value.
Doubly Linked List
4.7 Basic Operations on singly
Linked List
To create a linked list.
Traversing a linked list.
Insert New node at beginning (at first)
Insert new node at end
Insert new node at any location or in between the list
Inserting a node in to an ordered linear list.
Delete a first node (at beginning)
Delete a last node (at end)
Delete a node on basis of node number
Searching element in linked list
Count the number of nodes in linked list.
Concept of Availability List
• Whenever we insert a new node in linked list ,we have to take a free
node from availability list. Availability list contains the chain of free
nodes in which AVAIL pointer points to first node.
• We have to do following process to make a node free from
availability list.
• Initially we have availability list in which AVAIL pointer points to the
first node of it.
• When we want a free node from it, first we have to check that
availability list is empty or not.
• If AVAIL=NULL
• Then “AVAILABILITY STACK UNDERFLOW”
Concept of Availability List
• If there are free nodes available ,then NEW pointer pointing to
the AVAIL (first node of AVAILABILTY LIST)and AVAIL is now
pointing to the LINK(AVAIL)that means AVAIL pointer points
to the second node now and first node has been free to insert.
This code written by
• NEW AVAIL
• AVAIL LINK(AVAIL)
• INFO(NEW) X
Concept of Availability List
4.7 Insertion in beginning of linked
list
4.7 Algorithm-Insertion in beginning of
linked list
• Algorithm: INSERT_START(X,HEAD)
• Step 1: [Underflow?]
If AVAIL=NULL then
Write (“Availability List is Empty”)
return(HEAD)
• Step 2: [Obtain Address of next free node]
NEW AVAIL
• Step 3: [Remove free node from availability stack]
AVAIL LINK(AVAIL)
4.7 Algorithm-Insertion in beginning of
linked list
• Step 4: [Initialize field of new node and insert]
INFO(NEW) X
If HEAD=NULL
Then LINK(NEW) NULL
Return(NEW)
else
LINK(NEW) HEAD
HEAD NEW
• Step 5: [return address of new node]
return(HEAD)
4.7 Insertion at end in linked list
4.7 Algorithm-Insertion at end in linked
list
• Algorithm: INSERT_END(X,HEAD)
• Step 1: [Underflow?]
If AVAIL=NULL then
Write (“Availability List is Empty”)
return(HEAD)
• Step 2: [Obtain Address of next free node]
NEW AVAIL
• Step 3: [Remove free node from availability stack]
AVAIL LINK(AVAIL)
4.7 Algorithm-Insertion at end in linked
list
• Step 4: [Initialize field of new node]
INFO(NEW) x
LINK(NEW) NULL
• Step 5: [is the list empty?]
If HEAD=NULL then
HEAD NEW
return(NEW)
• Step 6: [initialize search for last node]
TEMP HEAD
4.7 Algorithm-Insertion at end in linked
list
• Step 7: [search for end of the list]
repeat while (LINK(TEMP)≠NULL)
TEMP LINK(TEMP)
• Step 8: [set link field of last node to NEW]
LINK(TEMP) NEW
• Step 9:[return head node pointer]
return(HEAD)
4.7 Insertion in ordered (sorted )linked
list
4.7 Algorithm-Insertion in ordered
linked list
• Algorithm: INSERT_ORDERED(X,HEAD)
• Step 1: [Underflow?]
If AVAIL=NULL then
Write (“Availability List is Empty”)
return(HEAD)
• Step 2: [Obtain Address of next free node]
NEW AVAIL
• Step 3: [Remove free node from availability stack]
AVAIL LINK(AVAIL)
4.7 Algorithm-Insertion at end in linked
list
• Step 4: [Initialize field of new node]
INFO(NEW) x
• Step 5: [is the list empty?]
If HEAD=NULL
Then LINK(NEW)NULL
return(NEW)
• Step 6: [does the new node precede all other nodes?]
If INFO(NEW) <= INFO(HEAD) Then
LINK(NEW) HEAD
HEAD NEW
return(HEAD)
4.7 Algorithm-Insertion at end in linked
• Step 7: [initialize temporary pointer]
list
TEMP HEAD
PREV TEMP
• Step 8: [search for predecessor of new node]
repeat while TEMP≠NULL and INFO(NEW)>=INFO(TEMP)
PREV TEMP
TEMP LINK(TEMP)
• Step 9: [set LINK fields of NEW node and its predecessor]
LINK(PREV) NEW
LINK(NEW) TEMP
• Step 10: [return head node]
return(head)
4.7 Algorithm-Insertion before given position
in linked list
• Algorithm: INSERT_BEF_POS(X,HEAD,POS)
• Step 1: [Underflow?]
If AVAIL=NULL then
Write (“Availability List is Empty”)
return(HEAD)
• Step 2: [Obtain Address of next free node]
NEW AVAIL
• Step 3: [Remove free node from availability stack]
AVAIL LINK(AVAIL)
4.7 Algorithm-Insertion before given position
in linked list
• Step 4: [Initialize field of new node]
INFO(NEW) x
• Step 5: [is the list empty?]
If HEAD=NULL
Then LINK(NEW)NULL
HEAD NEW
return(HEAD)
• Step 6: [does the new node precede all other nodes?]
If POS=1 Then
LINK(NEW) HEAD
HEAD NEW
return(HEAD)
4.7 Algorithm-Insertion before given position
in linked list
• Step 7: [initialize temporary pointers and loop variable]
TEMP HEAD
PREV TEMP
i 1
• Step 8: [search for position of new node]
repeat while i<POS and TEMP != NULL
PREV TEMP
TEMP LINK(TEMP)
i i+1
4.7 Algorithm-Insertion at end in linked
list
• Step 9: [set LINK fields of NEW node and its predecessor]
if(TEMP=NULL) then
Write(“Enter valid position”)
else
LINK(PREV) NEW
LINK(NEW) TEMP
• Step 10: [return head node]
return(head)
4.7 Algorithm-Insertion after given position
in linked list
• Algorithm: INSERT_AFT_POS(X,HEAD,POS)
• Step 1: [Underflow?]
If AVAIL=NULL then
Write (“Availability List is Empty”)
return(HEAD)
• Step 2: [Obtain Address of next free node]
NEW AVAIL
• Step 3: [Remove free node from availability stack]
AVAIL LINK(AVAIL)
4.7 Algorithm-Insertion after given position
in linked list
• Step 4: [Initialize field of new node]
INFO(NEW) x
• Step 5: [is the list empty?]
If HEAD=NULL
Then LINK(NEW)NULL
HEAD NEW
return(HEAD)
• Step 6: [does the new node precede all other nodes?]
If POS=1 Then
LINK(NEW) LINK(HEAD)
LINK(HEAD) NEW
return(HEAD)
4.7 Algorithm-Insertion after given position
in linked list
• Step 7: [initialize temporary pointers and loop variable]
TEMP HEAD
i 1
• Step 8: [search for position of new node]
repeat while i<POS and TEMP != NULL
TEMP LINK(TEMP)
i i+1
4.7 Algorithm-Insertion after given position
in linked list
• Step 9: [set LINK fields of NEW node and its predecessor]
if(TEMP=NULL) then
Write(“Enter valid position”)
else
LINK(NEW) LINK(TEMP)
LINK(TEMP) NEW
• Step 10: [return head node]
return(head)
4.7 Delete node from beginning in
singly linked list
4.7 Algorithm-Deletion from beginning
in linked list
• Algorithm: DELETE_BEG(HEAD)
• Step 1:[is list empty?]
If HEAD = NULL then
Write (“Linked List is Empty”)
• Step 2: [initialize temporary variable]
TEMP HEAD
• Step 3:[delete node]
If LINK(HEAD) = NULL then
HEAD NULL
Else
HEAD LINK(HEAD)
4.7 Algorithm-Deletion from beginning
in linked list
• Step 4: [return node to the availability list]
LINK(TEMP) AVAIL
AVAIL TEMP
Return()
4.7 Delete node from end in singly
linked list
4.7 Algorithm-Deletion from end in
linked list
• Algorithm: DELETE_END(HEAD)
• Step 1:[is list empty?]
If HEAD = NULL then
Write (“Linked List is Empty”)
• Step 2: [initialize temporary variable]
TEMP HEAD
• Step 3:[delete node]
If LINK(HEAD) = NULL then
HEAD NULL
4.7 Algorithm-Deletion from end in
linked list
Else
TEMP HEAD
PREVTEMP
repeat while(LINK(TEMP) ≠NULL)
PREVTEMP
TEMPLINK(TEMP)
LINK(PREV)NULL
• Step 4: [return node to the availability list]
LINK(TEMP) AVAIL
AVAIL TEMP
Return()
4.7 Count number of nodes in singly
linked list
4.7 Algorithm-Count nodes in linked list
• Algorithm: Count(HEAD)
• Step 1:[is list empty?]
If HEAD = NULL then
Write (“Linked List is Empty”)
• Step 2: [initialize temporary variable and counter ]
TEMP HEAD
count 1
• Step 3: [process the list until end of list ]
repeat while(LINK(TEMP) ≠NULL)
count count + 1
TEMPLINK(TEMP)
4.7 Algorithm-Count nodes in linked list
• Step 4: [return count]
Return(count)
4.7 Search node in singly linked list
hea
d
hea
d
4.7 Algorithm-Search node in linked list
• Algorithm: Search(HEAD,VAL)
• Step 1:[is list empty?]
If HEAD = NULL then
Write (“Linked List is Empty”)
return()
• Step 2: [initialize temporary variable and position ]
TEMP HEAD
POS 1
4.7 Algorithm-Search node in linked list
• Step 3: [Search Element ]
repeat while( INFO(TEMP)!=VAL and LINK(TEMP) ≠NULL)
POS POS + 1
TEMPLINK(TEMP)
if(INFO(TEMP)≠VAL)
then write(“NODE IS NOT IN THE LIST”)
return()
else write(“NODE IS FOUND AT POSITION”)
write(POS)
• Step 4: [FINISHED]
EXIT
4.8 Concept of Circular linked list
• A circular linked list is a sequence of elements in which every
element has a link to its next element in the sequence and the
last element has a link to the first element.
• In a circular linked list, we can perform all the operations as
we performed in singly linked list.
4.9 Difference between Singly and
Feature
Circular
Singly Linked List
Linked List
Circular Linked List
Structure Each node points to the Each node points to the next node, but the
next node, and the last last node points back to the first node
node points to null. (head), forming a loop.
End Node The last node's pointer is The last node’s pointer points to the head
null, indicating the end of node, making it circular (no null
the list. termination).
Traversal is typically one- Traversal continues indefinitely in a circular
Traversal
way (from head to the last manner unless a stopping condition is
Direction
node). implemented.
Traversal Traversal stops when the Traversal requires a condition to stop, such
Stopping last node is reached (null). as detecting the head node or keeping a
count of traversed nodes.
Use Cases Suitable for simple, one- Useful in scenarios requiring continuous
directional data traversal, like round-robin scheduling or
structures. circular buffers
Ease of Simpler to implement due Slightly more complex, as special care is
4.10 Representation of doubly linked list
• Node Structure:In a doubly linked list, each node has:
• A data field (to store the value).
• A prev pointer (to point to the previous node).
• A next pointer (to point to the next node).
struct Node {
int data; // Data to be stored in the node
struct Node* prev; // Pointer to the previous node
struct Node* next; // Pointer to the next node
};
4.11 Difference between Singly and
Feature Singly
Doubly
Linked List
linked list
Doubly Linked List
Structure Each node contains data Each node contains data, a pointer to the
and a pointer to the next next node, and a pointer to the previous
node. node.
Number of One pointer (to the next Two pointers (one to the next node and one
Pointers node). to the previous node).
Can be traversed in only Can be traversed in both directions (from
Traversal
one direction (from head head to tail and tail to head).
Direction
to tail).
Memory Requires less memory as it Requires more memory as it stores two
Usage stores only one pointer per pointers per node (next and previous).
node.
Use Cases Suitable for simple data Suitable for more complex data structures
structures where reverse that need forward and backward traversal
traversal isn't required. (e.g., browser history, music playlists).
Traversal Less efficient if reverse More efficient for reverse traversal since
Efficiency traversal is needed you can move backward using the previous
4.12 Applications of Linked List
Dynamic Memory Allocation: Used to manage free memory blocks
in dynamic memory systems like malloc() in C.
Implementing Stacks and Queues: Enables efficient insertion and
deletion in stack (LIFO) and queue (FIFO) operations.
Graph Representation (Adjacency List): Used to represent graphs,
where each vertex points to a linked list of adjacent vertices.
Round-Robin Scheduling: Circular linked lists help in processes that
require repeated traversal, such as CPU scheduling.
Undo/Redo Functionality: Doubly linked lists allow easy backward
and forward navigation in applications like text editors.
Hash Table Collision Handling (Chaining): Linked lists resolve hash
collisions by storing multiple keys in the same bucket.