TITLE: TO IMPLEMENT DOUBLY LINKED LIST
INTRODUCTION
In this lab work, we will be implementing a doubly linked list in the C programming
language. A doubly linked list is a linear data structure where each node contains data, a
pointer to the next node, and a pointer to the previous node. This bidirectional linkage allows
traversal in both forward and backward directions, making it more flexible than a singly
linked list. We will perform various operations such as insertion, deletion, searching, and
counting the number of nodes. The program will feature a menu-driven interface that enables
users to interact with the linked list and carry out these operations dynamically.
THEORY
A doubly linked list is a collection of nodes where each node contains three parts:
Data: The value stored in the node.
Next Pointer: A pointer to the next node in the list.
Previous Pointer: A pointer to the previous node in the list.
Unlike singly linked lists, doubly linked lists allow traversal in both directions. The first
node's previous pointer and the last node's next pointer point to NULL.
The fundamental operations performed in this lab include:
• Insertion: Adding a node at the beginning, end, or a specific position.
• Deletion: Removing a node from the beginning, end, or a specific position.
• Display: Traversing the linked list and printing all elements.
• Search: Finding an element in the linked list.
• Count: Determining the total number of nodes in the linked list.
Insertion Operations
1. Insert at Front
i. Create a new node with the given data.
ii. Set newNode->next to point to the current head.
iii. Set newNode->prev to NULL.
iv. If the list is not empty, set head->prev to newNode.
v. Update the head to point to newNode.
2. Insert at End
i. Create a new node with the given data.
ii. If the list is empty, set head to newNode and return.
iii. Traverse to the last node.
iv. Set lastNode->next to newNode.
v. Set newNode->prev to lastNode.
vi. Set newNode->next to NULL.
1
3. Insert at a Specified Position
i. Create a new node with the given data.
ii. If position is 0, follow the steps of Insert at Front.
iii. Traverse to the (position - 1)th node.
iv. Set newNode->next to prevNode->next.
v. Set newNode->prev to prevNode.
vi. If prevNode->next is not NULL, set prevNode->next->prev to newNode.
vii. Set prevNode->next to newNode.
Deletion Operations
1. Delete from Front
i. If the list is empty, return.
ii. Store the head node in a temporary variable.
iii. Update head to head->next.
iv. If the new head is not NULL, set head->prev to NULL.
v. Free the temporary node.
2. Delete from End
i. If the list is empty, return.
ii. If there is only one node, set head to NULL and free the node.
iii. Traverse to the last node.
iv. Set lastNode->prev->next to NULL.
v. Free the last node.
3. Delete from a Specified Position
i. If the list is empty, return.
ii. If position is 0, follow the steps of Delete from Front.
iii. Traverse to the node at the given position.
iv. Set delNode->prev->next to delNode->next.
v. If delNode->next is not NULL, set delNode->next->prev to delNode->prev.
vi. Free the delNode.
2
TASK PERFORMED
Write a menu-driven program to implement doubly linked list.
SOURCE CODE
#include <stdio.h>
#include <stdlib.h>
struct Node{
int info;
struct Node *prev;
struct Node *next;
};
struct Node *head=NULL;
void menu(){ // Function to display menu
printf("\n-----MAIN MENU-----\n");
printf("-------------------\n");
printf("1.INSERT\n2.DELETE\n3.DISPLAY\n4.SEARCH\n5.COUNT\n6.EXIT\n");
}
void insertMenu(){ // Function to display insert menu
printf("\n-----INSERT MENU-----\n");
printf("---------------------\n");
printf("1.AT THE BEGINNING\n2.AT THE END\n3.AT A SPECIFIED POSITION\
n4.BACK\n");
}
void deleteMenu(){ // Function to display delete menu
printf("\n-----DELETE MENU------\n");
printf("----------------------\n");
printf("1.AT THE BEGINNING\n2.AT THE END\n3.AT A SPECIFIED POSITION\
n4.BACK\n");
}
struct Node* createNewNode(int data){ // Function to create a new node
struct Node* newNode=(struct Node*)malloc(sizeof(struct Node));
newNode->info=data;
newNode->prev=NULL;
newNode->next=NULL;
return newNode;
}
int count(){ // Function to count the number of nodes
int count=0;
struct Node *temp=head;
while(temp!=NULL){
count++;
temp=temp->next;
}
3
return count;
}
void insrtFront(int data){ // Function to insert a new nonde at the beginning
struct Node* newNode=createNewNode(data);
if (head==NULL){
head=newNode;
}else{
newNode->next=head;
head=newNode;
}
}
void insrtLast(int data){ // Function to insert a new nonde at the end
struct Node *temp;
struct Node* newNode=createNewNode(data);
if(head==NULL){
head=newNode;
}else{
temp=head;
while(temp->next!=NULL){
temp=temp->next;
}
temp->next=newNode;
newNode->prev=temp;
}
}
void insrtSpeci(int data,int pos) { // Function to insert a new nonde at the specified
position
struct Node *temp=head;
struct Node* newNode=createNewNode(data);
int c=count();
if(head==NULL){
printf("Void insertion\n");
return;
}else{
if(pos<1 || pos>c+1){
printf("Invalid position");
} else {
if(pos==1){
insrtFront(data);
} else if(pos==c+1){
insrtLast(data);
} else {
for(int i=1;i<pos-1;i++){
temp=temp->next;
4
}
newNode->next=temp->next;
newNode->prev=temp;
temp->next->prev=newNode;
temp->next=newNode;
}
}
}
}
void dltFront(){ // Function to delete node at front
struct Node *temp=head;
printf("Deleted: %d\n",temp->info);
if(head==NULL){
printf("Void deletion\n");
return;
}else{
head=head->next;
head->prev=NULL;
}
free(temp);
}
void dltLast(){// Function to delete node at the last
if(head==NULL){
printf("[ERROR] Void deletion\n");
return;
}
struct Node *temp=head;
if(head->next==NULL){
printf("Deleted: %d\n",temp->info);
head=NULL;
}else{
while(temp->next!=NULL){
temp=temp->next;
}
printf("Deleted: %d\n",temp->info);
temp->prev->next=NULL;
}
free(temp);
}
void dltSpeci(){ // Function to delete node at a specified position
int pos;
struct Node *hold;
struct Node *temp=head;
int c=count();
5
printf("Enter the position: ");
scanf("%d",&pos);
if(head==NULL){
printf("Void deletion\n");
return;
} else {
if(pos<1 || pos>c){
printf("Invalid position");
} else {
if(pos==1){
dltFront();
} else if(pos==c){
dltLast();
} else {
for(int i=1;i<pos-1;i++){
temp=temp->next;
}
hold=temp->next;
printf("Deleted: %d\n",hold->info);
temp->next=hold->next;
hold->next->prev=temp;
free(hold);
}
}
}
}
void display(){ // Function to display the nodes
struct Node *temp=head;
if (temp==NULL) {
printf("Empty List\n");
return;
}
printf("Nodes are: \n");
while(temp!=NULL){
printf("%d\t",temp->info);
temp=temp->next;
}
}
void search(){ // Function to search node in the linked list
int key,i=0;
struct Node *temp=head;
printf("Enter data to find: ");
scanf("%d",&key);
while(temp!=NULL){
6
i++;
if(key==temp->info){
printf("Data found at position %d.",i);
return;
}
temp=temp->next;
}
printf("Data not found.");
}
void prog(){
int ch,ch1,ch2,d,p;
while (1){
menu();
printf("Enter your choice: ");
scanf("%d", &ch);
switch (ch){
case 1:
insertMenu();
printf("Enter your choice: ");
scanf("%d", &ch1);
if(ch1==3){
printf("Enter position: ");
scanf("%d",&p);
}
if(ch1!=4){
printf("Enter data: ");
scanf("%d", &d);
}
switch (ch1){
case 1:
insrtFront(d);
break;
case 2:
insrtLast(d);
break;
case 3:
insrtSpeci(d,p);
break;
case 4:
break;
default:
printf("Invalid choice\n");
}
break;
7
case 2:
deleteMenu();
printf("Enter your choice: ");
scanf("%d", &ch2);
switch (ch2){
case 1:
dltFront();
break;
case 2:
dltLast();
break;
case 3:
dltSpeci();
break;
case 4:
prog();
break;
default:
printf("Invalid choice\n");
}
break;
case 3:
display();
break;
case 4:
search();
break;
case 5:
printf("Number of nodes: %d",count());
break;
case 6:
exit(0);
break;
default:
printf("Invalid choice\n");
}
}
}
int main(){
prog();
return 0;
}
8
OUTPUT
Main menu:
Insert menu:
Delete menu:
Void insertion:
9
Void deletion :
Insert at the beginning:
Insert at the end:
Insert at a specified position:
Insert at invalid position:
Delete at specified position:
Delete at invalid position:
Delete at front:
Delete at last:
Display:
10
Empty list display:
Searching valid nodes:
Searching invalid nodes:
Count:
Invalid choice:
Exit:
DISCUSSION
In this lab exercise, a doubly linked list was implemented, demonstrating the core operations
that can be performed on this data structure. A doubly linked list is a type of linked list in
which each node contains two pointers: one pointing to the next node and another pointing to
the previous node. This allows traversal in both directions. The program provides a menu-
11
driven interface to perform various operations on the list, such as inserting, deleting,
displaying, searching, and counting the number of nodes. The functions are organized into
sub-menus for ease of navigation and to keep the code modular.
The insert and delete operations in the doubly linked list are implemented in different ways to
give the user flexibility. Nodes can be inserted at the front, at the end, or at a specified
position in the list. Similarly, nodes can be deleted from the front, from the end, or from a
specific position. These operations require careful handling of the pointers to maintain the
integrity of the doubly linked list. Special attention is given to the edge cases such as when
the list is empty or when invalid positions are entered by the user. The program ensures that
the list is properly updated after each operation, and memory is freed when nodes are deleted.
The display function ensures that the user can visualize the current state of the list. It
traverses through the nodes from head to tail, printing each node's data. The search function
allows users to find the position of a specific data value in the list, which is important for
real-world applications like searching for an item in a collection. The count function provides
the number of elements in the list, which is useful for understanding the list’s size. While the
implementation is simple, it demonstrates fundamental concepts such as dynamic memory
allocation, pointer manipulation, and the importance of maintaining proper links between
nodes in a doubly linked list.
CONCLUSION
In conclusion, this lab exercise effectively implemented the operations of a doubly linked list.
The functions for insertion, deletion, traversal, searching, and counting nodes were
successfully integrated into a menu-driven interface, making the program user-friendly. The
implementation of the doubly linked list helped in understanding pointer manipulation,
memory management, and edge cases. Through this exercise, the program provides a
foundation for more advanced data structures and operations, which are critical in building
more complex systems like databases or caches. Overall, the lab successfully reinforced the
concepts of linked list operations, pointer-based navigation, and the dynamic nature of
memory in C programming.
12