Exp 6 - Dsa Lab File

You might also like

Download as docx, pdf, or txt
Download as docx, pdf, or txt
You are on page 1of 38

EXPERIMENT NO-6: LINKED LIST

A linked list is a fundamental data structure in computer science used for organizing and
storing a collection of elements, called nodes, in a linear fashion. Each node in a linked list
contains two main components:
Data: This component stores the actual value or information that the node is intended to hold.
Pointer/Reference: This component points to the next node in the sequence. In a singly linked
list, each node has a pointer/reference to the next node, while in a doubly linked list, each
node has pointers to both the next and previous nodes.
Linked lists can be categorized into several types, including:
Singly Linked List: In this type of linked list, each node points to the next node in the
sequence, forming a unidirectional chain. The last node typically points to null to indicate the
end of the list.
Doubly Linked List: Each node in a doubly linked list has pointers to both the next and
previous nodes, forming a bidirectional chain. This allows for easy traversal in both
directions.
Circular Linked List: A circular linked list is a variation of a linked list in which the last node
points back to the first node, creating a closed loop. This can be either singly or doubly
linked.

LINKED LIST REPRESENTATION:


Linked list can be visualized as a chain of nodes, where every node points to the next node.

As per the above illustration, following are the important points to be considered.

 Linked List contains a link element called first (head).


 Each link carries a data field(s) and a link field called next.
 Each link is linked with its next link using its next link.
 Last link carries a link as null to mark the end of the list.

TYPES OF LINKED LIST


Following are the various types of linked list.

Singly Linked Lists

Singly linked lists contain two “buckets” in one node; one bucket holds the data and the other
bucket holds the address of the next node of the list. Traversals can be done in one direction
only as there is only a single link between two nodes of the same list.

Doubly Linked Lists

Doubly Linked Lists contain three “buckets” in one node; one bucket holds the data and the
other buckets hold the addresses of the previous and next nodes in the list. The list is
traversed twice as the nodes in the list are connected to each other from both sides.

Circular Linked Lists

Circular linked lists can exist in both singly linked list and doubly linked list.
Since the last node and the first node of the circular linked list are connected, the traversal in
this linked list will go on forever until it is broken.
SINGLY LINKED LIST
Algorithm: -

Basic Operations in the Linked Lists

The basic operations in the linked lists are insertion, deletion, searching, display, and deleting
an element at a given key. These operations are performed on Singly Linked Lists as given
below −

 Insertion − Adds an element at the beginning of the list.


 Deletion − Deletes an element at the beginning of the list.
 Display − Displays the complete list.
 Search − Searches an element using the given key.
 Delete − Deletes an element using the given key.

 Insertion Operation
Insertion in linked list can be done in three different ways. They are explained as follows –

 Insertion at Beginning
In this operation, we are adding an element at the beginning of the list.

Algorithm

1. START
2. Create a node to store the data
3. Check if the list is empty
4. If the list is empty, add the data to the node and assign the head pointer to it.
5 If the list is not empty, add the data to a node and link to the current head. Assign the head
to the newly added node.
6. END

 Insertion at Ending
In this operation, we are adding an element at the ending of the list.

Algorithm
1. START
2. Create a new node and assign the data
3. Find the last node
4. Point the last node to new node
5. END

 Insertion at a Given Position


In this operation, we are adding an element at any position within the list.

Algorithm

1. START
2. Create a new node and assign data to it
3. Iterate until the node at position is found
4. Point first to new first node
5. END

 Deletion Operation
Deletion in linked lists is also performed in three different ways. They are as follows –

 Deletion at Beginning
In this deletion operation of the linked, we are deleting an element from the beginning of the
list. For this, we point the head to the second node.

Algorithm

1. START
2. Assign the head pointer to the next node in the list
3. END

 Deletion at Ending
In this deletion operation of the linked, we are deleting an element from the ending of the list.

Algorithm

1. START
2. Iterate until you find the second last element in the list.
3. Assign NULL to the second last element in the list.
4. END

 Deletion at a Given Position


In this deletion operation of the linked, we are deleting an element at any position of the
list.

Algorithm

1. START
2. Iterate until find the current node at position in the list
3. Assign the adjacent node of current node in the list to its previous node.
4. END

 Search Operation
Searching for an element in the list using a key element. This operation is done in the same
way as array search; comparing every element in the list with the key element given.

Algorithm

1 START
2 If the list is not empty, iteratively check if the list contains the key
3 If the key element is not present in the list, unsuccessful search
4 END

 Traversal Operation
The traversal operation walks through all the elements of the list in an order and displays the
elements in that order.

Algorithm

1. START
2. While the list is not empty and did not reach the end of the list, print the data in each node
3. END
ILLUSTRATIONS OF THE VARIOUS OPERATIONS OF
SINGLY LINKED LIST
#include<stdio.h>

#include<stdlib.h>

struct node

int data;

struct node *next;

};

struct node *head;

void beginsert ();

void lastinsert ();

void randominsert();

void begin_delete();

void last_delete();

void random_delete();

void display();

void search();

int main ()

int choice =0;

while(choice != 9)

{
printf("\n\n*********Main Menu*********\n");

printf("\nChoose one option from the following list ...\n");

printf("\n===============================================\n");

printf("\n1.Insert in begining\n2.Insert at last\n3.Insert at any random location\n4.Delete


from Beginning\n5.Delete from last\n6.Delete node after specified location\n7.Search for an
element\n8.Show\n9.Exit\n");

printf("\nEnter your choice:\n");

scanf("\n%d",&choice);

switch(choice)

case 1:

beginsert();

break;

case 2:

lastinsert();

break;

case 3:

randominsert();

break;

case 4:

begin_delete();

break;

case 5:

last_delete();

break;

case 6:
random_delete();

break;

case 7:

search();

break;

case 8:

display();

break;

case 9:

exit(0);

break;

default:

printf("Please enter valid choice..");

void beginsert()

struct node *ptr;

int item;

ptr = (struct node *) malloc(sizeof(struct node *));

if(ptr == NULL)

printf("\nOVERFLOW");

}
else

printf("\nEnter value\n");

scanf("%d",&item);

ptr->data = item;

ptr->next = head;

head = ptr;

printf("\nNode inserted");

void lastinsert()

struct node *ptr,*temp;

int item;

ptr = (struct node*)malloc(sizeof(struct node));

if(ptr == NULL)

printf("\nOVERFLOW");

else

printf("\nEnter value?\n");

scanf("%d",&item);

ptr->data = item;
if(head == NULL)

ptr -> next = NULL;

head = ptr;

printf("\nNode inserted");

else

temp = head;

while (temp -> next != NULL)

temp = temp -> next;

temp->next = ptr;

ptr->next = NULL;

printf("\nNode inserted");

void randominsert()

int i,loc,item;

struct node *ptr, *temp;

ptr = (struct node *) malloc (sizeof(struct node));


if(ptr == NULL)

printf("\nOVERFLOW");

else

printf("\nEnter element value");

scanf("%d",&item);

ptr->data = item;

printf("\nEnter the location after which you want to insert ");

scanf("\n%d",&loc);

temp=head;

for(i=0;i<loc;i++)

temp = temp->next;

if(temp == NULL)

printf("\ncan't insert\n");

return;

ptr ->next = temp ->next;

temp ->next = ptr;

printf("\nNode inserted");
}

void begin_delete()

struct node *ptr;

if(head == NULL)

printf("\nList is empty\n");

else

ptr = head;

head = ptr->next;

free(ptr);

printf("\nNode deleted from the begining ...\n");

void last_delete()

struct node *ptr,*ptr1;

if(head == NULL)

printf("\nlist is empty");

else if(head -> next == NULL)


{

head = NULL;

free(head);

printf("\nOnly node of the list deleted ...\n");

else

ptr = head;

while(ptr->next != NULL)

ptr1 = ptr;

ptr = ptr ->next;

ptr1->next = NULL;

free(ptr);

printf("\nDeleted Node from the last ...\n");

void random_delete()

struct node *ptr,*ptr1;

int loc,i;

printf("\n Enter the location of the node after which you want to perform deletion \n");

scanf("%d",&loc);
ptr=head;

for(i=0;i<loc;i++)

ptr1 = ptr;

ptr = ptr->next;

if(ptr == NULL)

printf("\nCan't delete");

return;

ptr1 ->next = ptr ->next;

free(ptr);

printf("\nDeleted node %d ",loc+1);

void search()

struct node *ptr;

int item,i=0,flag;

ptr = head;

if(ptr == NULL)

printf("\nEmpty List\n");

}
else

printf("\nEnter item which you want to search?\n");

scanf("%d",&item);

while (ptr!=NULL)

if(ptr->data == item)

printf("item found at location %d ",i+1);

flag=0;

else

flag=1;

i++;

ptr = ptr -> next;

if(flag==1)

printf("Item not found\n");

}
void display()

struct node *ptr;

ptr = head;

if(ptr == NULL)

printf("Nothing to print");

else

printf("\nprinting values . . . . .\n");

while (ptr!=NULL)

printf("\n%d",ptr->data);

ptr = ptr -> next;

}
OUTPUT:-
STACK IMPLEMENTATION BY LINKED LIST
ALGORITHM: -
Basic operations of stack
• push(): it pushes an element into the stack data structure.
• pop(): it removes the top element of the stack.
• display(): it prints the contents of the stack in LIFO order.

push()
ALGORITHM:-

1. Check stack overflow, i.e. if (size >= CAPACITY), then print “Stack overflow” error
message. Otherwise move to below step.
2. Create a new stack node using dynamic memory allocation i.e. struct stack *
newNode = (struct stack *) malloc(sizeof(struct stack));.
3. Assign data to the newly created node using newNode->data = data;.
4. Link new node with the current stack top most element. Say newNode->next = top;
and increment size count by 1.
5. Finally make sure the top of stack should always be the new node i.e. top = newNode;

pop()
ALGORITHM:-
1. If size <= 0 then throw “Stack is Empty” error, otherwise move to below step.
2. Assign the top most element reference to some temporary variable, say struct stack
*topNode = top;. Similarly copy data of stack top element to some variable say int data = top-
>data;.
3. Make second element of stack as top element i.e. top = top->next;.
4. Delete the top most element from memory using free(topNode);.
5. Decrement stack size by one and return data.
display()
ALGORITHM:-

• Assign top1=top.
• Check stack UNDERFLOW i.e. if (top1==NULL),print “STACK IS EMPTY”.
• while (top1 != NULL), display top1->data
• Assign top1 = top1->next
CODE:-
#include <stdio.h>

#include <stdlib.h>

#include <limits.h>

#define CAPACITY 10000

struct stack

int data;

struct stack *next;

} *top,*top1;

int size = 0;

void push(int element);

int pop();

void display();

int main()

int choice, data;

while(1)

printf("------------------------------------\n");

printf(" STACK IMPLEMENTATION USING LINKED LIST \n");

printf("------------------------------------\n");

printf("1. Push\n");
printf("2. Pop\n");

printf("3. Display\n");

printf("4. Exit\n");

printf("------------------------------------\n");

printf("Enter your choice: ");

scanf("%d", &choice);

switch(choice)

case 1:

printf("Enter data to push into stack: ");

scanf("%d", &data);

push(data);

break;

case 2:

data = pop();

if (data != INT_MIN)

printf("Data => %d\n", data);

break;

case 3:

display();

break;

case 4:

printf("Exiting from app.\n");

exit(0);

break;
default:

printf("Invalid choice, please try again.\n");

printf("\n\n");

return 0;

void push(int element)

if (size >= CAPACITY)

printf("Stack Overflow, can't add more element to stack.\n");

return;

struct stack * newNode = (struct stack *) malloc(sizeof(struct stack));

newNode->data = element;

newNode->next = top;

top = newNode;

size++;

printf("Data pushed to stack.\n");

int pop()

int data = 0;
struct stack * topNode;

if (size <= 0 || !top)

printf("Stack is empty.\n");

return INT_MIN;

topNode = top;

data = top->data;

top = top->next;

free(topNode);

size--;

return data;

void display()

top1 = top;

if (top1 == NULL)

printf("Stack is empty");

return;

while (top1 != NULL)

printf("%d ", top1->data);

top1 = top1->next;
}

OUTPUT:-
QUEUE IMPLEMENTATION USING LINKED LIST

ALGORITHM: -

Operations on Linked Queue


There are three basic operations which can be implemented on the linked queues. The
operations are Insertion, Deletion and Display.

 Enqueue
Inserting an element in Queue.

ALGORITHM:-
Step 1 : Create a newNode with given value and set 'newNode → next' to
NULL.Also,allocate the space for the new node.

Step 2 : Check whether queue is Empty (rear == NULL)

Step 3 : If it is Empty then, set front = newNode and rear = newNode.

Step 4 : If it is Not Empty then, set rear → next = newNode and rear = newNode.

 Dequeue
Deleting an element from Queue.

ALGORITHM:-

Step 1 : Check whether queue is Empty (front == NULL).


Step 2 : If it is Empty, then display "Queue is Empty!!! " and terminate from the function
Step 3 : If it is Not Empty then, define a Node pointer 'temp' and set it to 'front'.
Step 4 : Then set 'front = front → next' and delete 'temp' (free(temp)).
 Display
ALGORITHM:-

Step 1 : Check whether queue is Empty (front == NULL).

Step 2 : If it is Empty then, display 'Queue is Empty!!!' and terminate the function.

Step 3 : If it is Not Empty then, define a Node pointer 'temp' and initialize with front.

Step 4 : Display 'temp → data -->' and move it to the next node. Repeat the same until 'temp'
reaches to 'rear' (temp → next != NULL).

Step 5 : Finally! Display 'temp → data --> NULL'.


CODE:-
#include <stdio.h>
#include <stdlib.h>

struct node
{
int data;
struct node* next;
};

struct node *front = NULL;


struct node *rear = NULL;

void enqueue(int d)
{
struct node* new_n;
new_n = (struct node*)malloc(sizeof(struct node));
new_n->data = d;
new_n->next = NULL;
if((front == NULL)&&(rear == NULL)){
front = rear = new_n;
}
else{
rear->next = new_n;
rear = new_n;
}

void display()
{
struct node* temp;
if((front == NULL)&&(rear == NULL)){
printf("\nQueue is Empty");
}
else{
temp = front;
while(temp){
printf(" %d ",temp->data);
temp = temp->next;
}
}
}

void dequeue()
{
struct node *temp;
temp = front;
if((front == NULL)&&(rear == NULL)){
printf("\nQueue is Empty");
}
else{
front = front->next;
free(temp);
}
}
int main()
{
{
int choice,data;
while(choice != 4)
{
printf("\n1.insert an element\n2.Delete an element\n3.Display the queue\n4.Exit\n");
printf("\nEnter your choice:");
scanf("%d",&choice);
switch(choice)
{
case 1:
printf("Enter the element to be inserted:");
scanf("%d",&data);
enqueue(data);
break;
case 2:
dequeue();
break;
case 3:
display();
break;
case 4:
exit(0);
break;
default:
printf("\nEnter valid choice??\n");
}
}
}
return 0;
}
OUTPUT:-
DOUBLY LINKED LIST
Doubly Linked List is a variation of Linked list in which navigation is possible in both ways,
either forward and backward easily as compared to Single Linked List. Following are the
important terms to understand the concept of doubly linked list.

 Link − Each link of a linked list can store a data called an element.
 Next − Each link of a linked list contains a link to the next link called Next.
 Prev − Each link of a linked list contains a link to the previous link called Prev.
 Linked List − A Linked List contains the connection link to the first link called First
and to the last link called Last.

DOUBLY LINKED LIST REPRESENTATION

As per the above illustration, following are the important points to be considered.

 Doubly Linked List contains a link element called first and last.
 Each link carries a data field(s) and a link field called next.
 Each link is linked with its next link using its next link.
 Each link is linked with its previous link using its previous link.
 The last link carries a link as null to mark the end of the list.

BASIC OPERATIONS
Following are the basic operations supported by a list.

 Insertion − Adds an element at the beginning of the list.


 Deletion − Deletes an element at the beginning of the list.
 Insert Last − Adds an element at the end of the list.
 Delete Last − Deletes an element from the end of the list.
 Insert After − Adds an element after an item of the list.
 Delete − Deletes an element from the list using the key.
 Display forward − Displays the complete list in a forward manner.
Insertion at the Beginning
In this operation, we create a new node with three compartments, one containing the data, the
others containing the address of its previous and next nodes in the list. This new node is
inserted at the beginning of the list.

Algorithm

1. START
2. Create a new node with three variables: prev, data, next.
3. Store the new data in the data variable
4. If the list is empty, make the new node as head.
5. Otherwise, link the address of the existing first node to the next variable of the new node,
and assign null to the prev variable.
6. Point the head to the new node.
7. END

Deletion at the Beginning


This deletion operation deletes the existing first nodes in the doubly linked list. The head is
shifted to the next node and the link is removed.

Algorithm

1. START
2. Check the status of the doubly linked list
3. If the list is empty, deletion is not possible
4. If the list is not empty, the head pointer is shifted to the next node.
5. END

Insertion at the End


In this insertion operation, the new input node is added at the end of the doubly linked list; if
the list is not empty. The head will be pointed to the new node, if the list is empty.

Algorithm

1. START
2. If the list is empty, add the node to the list and point the head to it.
3. If the list is not empty, find the last node of the list.
4. Create a link between the last node in the list and the new node.
5. The new node will point to NULL as it is the new last node.
6. END

IMPLEMENTATION OF DOUBLY LINKED LIST

#include <stdio.h>

#include <stdlib.h>

struct Node {

int data;

struct Node* next;

struct Node* prev;

};

void insertFront(struct Node** head, int data) {

struct Node* newNode = (struct Node*)malloc(sizeof(struct Node));

newNode->data = data;

newNode->next = (*head);

newNode->prev = NULL;

if ((*head) != NULL)

(*head)->prev = newNode;

(*head) = newNode;

void insertAfter(struct Node* prev_node, int data) {

if (prev_node == NULL) {

printf("previous node cannot be null");

return;

struct Node* newNode = (struct Node*)malloc(sizeof(struct Node));


newNode->data = data;

newNode->next = prev_node->next;

prev_node->next = newNode;

newNode->prev = prev_node;

if (newNode->next != NULL)

newNode->next->prev = newNode;

void insertEnd(struct Node** head, int data) {

struct Node* newNode = (struct Node*)malloc(sizeof(struct Node));

newNode->data = data;

newNode->next = NULL;

struct Node* temp = *head;

if (*head == NULL) {

newNode->prev = NULL;

*head = newNode;

return;

while (temp->next != NULL)

temp = temp->next;

temp->next = newNode;

newNode->prev = temp;

void deleteNode(struct Node** head, struct Node* del_node) {

if (*head == NULL || del_node == NULL)


return;

if (*head == del_node)

*head = del_node->next;

if (del_node->next != NULL)

del_node->next->prev = del_node->prev;

if (del_node->prev != NULL)

del_node->prev->next = del_node->next;

free(del_node);

void displayList(struct Node* node) {

struct Node* last;

while (node != NULL) {

printf("%d->", node->data);

last = node;

node = node->next;

if (node == NULL)

printf("NULL\n");

int main() {

struct Node* head = NULL;

insertEnd(&head, 5);
insertFront(&head, 1);

insertFront(&head, 6);

insertEnd(&head, 9);

insertAfter(head, 11);

insertAfter(head->next, 15);

displayList(head);

deleteNode(&head, head->next->next->next->next->next);

displayList(head);
}
OUTPUT:-
CONCLUSION:-
A doubly linked list is a versatile data structure that offers several advantages over singly
linked lists. It allows for efficient traversal in both directions, making it suitable for a wide
range of applications. Additionally, it is well-suited for various applications, including
implementing data structures like stacks, queues.They are a valuable data structure that offers
bidirectional traversal and efficient insertion and deletion operations, at the cost of increased
memory usage and a somewhat more complex implementation. The choice to use a doubly
linked list should be based on the specific requirements of your application, as it may provide
significant benefits in certain scenarios while being less suitable in others.

You might also like