0% found this document useful (0 votes)
2 views

Linked List Data Structure Programms (1)

The document provides an overview of operations on singly and doubly linked lists, including insertion, deletion, searching, reversing, and calculating the length of the list. Each operation is accompanied by C code examples and explanations detailing the functionality and logic behind the code. The document serves as a comprehensive guide for understanding and implementing linked list data structures.

Uploaded by

pavithragowda077
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
2 views

Linked List Data Structure Programms (1)

The document provides an overview of operations on singly and doubly linked lists, including insertion, deletion, searching, reversing, and calculating the length of the list. Each operation is accompanied by C code examples and explanations detailing the functionality and logic behind the code. The document serves as a comprehensive guide for understanding and implementing linked list data structures.

Uploaded by

pavithragowda077
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 27

LINKED LIST DATA STRUCTURE

1. Singly Linked List: Insert Node at the Beginning


#include <stdio.h>
#include <stdlib.h>

// Definition of the Node structure


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

// Function to insert a node at the beginning of the list


void insertAtBeginning(struct Node** head, int data) {
struct Node* newNode = (struct Node*)malloc(sizeof(struct Node)); //
Create a new node
newNode->data = data; // Assign the data to the new node
newNode->next = *head; // Point the next of the new node to the current
head
*head = newNode; // Update the head to the new node
}

// Function to display the linked list


void display(struct Node* head) {
while (head != NULL) {
printf("%d -> ", head->data); // Print the current node's data
head = head->next; // Move to the next node
}
printf("NULL\n");
}

int main() {
struct Node* head = NULL; // Initialize the head to NULL
insertAtBeginning(&head, 10); // Insert 10 at the beginning
insertAtBeginning(&head, 20); // Insert 20 at the beginning
insertAtBeginning(&head, 30); // Insert 30 at the beginning
display(head); // Display the list
return 0;
}

/* Explanation:
1. The program defines a `Node` structure to represent a node in the list.
2. The `insertAtBeginning` function inserts a new node at the start of the
list.
3. A new node is created using `malloc`, its data is set, and it is linked to
the current head.
4. The head is updated to point to the newly inserted node.
5. The `display` function traverses the list from the head, printing each
node's data.
6. In `main`, we initialize the list and perform three insertions.
7. After inserting, we call `display` to print the entire list.
8. The nodes are inserted in reverse order since each new node becomes the
head.
9. The list is displayed as "30 -> 20 -> 10 -> NULL".
10. This demonstrates a basic insertion operation in a singly linked list.
*/

2. Singly Linked List: Insert Node at the End


#include <stdio.h>
#include <stdlib.h>

// Definition of the Node structure


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

// Function to insert a node at the end of the list


void insertAtEnd(struct Node** head, int data) {
struct Node* newNode = (struct Node*)malloc(sizeof(struct Node)); //
Create a new node
struct Node* temp = *head; // Temporary pointer to traverse the list
newNode->data = data; // Set the data for the new node
newNode->next = NULL; // The new node's next will be NULL (end of the
list)

if (*head == NULL) {
*head = newNode; // If the list is empty, make the new node the head
return;
}
while (temp->next != NULL) {
temp = temp->next; // Traverse to the end of the list
}
temp->next = newNode; // Link the last node to the new node
}

// Function to display the linked list


void display(struct Node* head) {
while (head != NULL) {
printf("%d -> ", head->data); // Print the data of the current node
head = head->next; // Move to the next node
}
printf("NULL\n");
}

int main() {
struct Node* head = NULL; // Initialize the head to NULL
insertAtEnd(&head, 10); // Insert 10 at the end
insertAtEnd(&head, 20); // Insert 20 at the end
insertAtEnd(&head, 30); // Insert 30 at the end
display(head); // Display the list
return 0;
}

/* Explanation:
1. The `insertAtEnd` function adds a new node at the end of the list.
2. A new node is created with `malloc`, and its `data` is set.
3. If the list is empty, the new node becomes the head.
4. Otherwise, the program traverses the list to reach the last node.
5. The `next` pointer of the last node is updated to point to the new node.
6. The `display` function prints the entire list from the head to the end.
7. In `main`, three nodes are inserted into the list.
8. The list is displayed as "10 -> 20 -> 30 -> NULL".
9. This operation ensures that nodes are appended at the end, regardless of
the list's size.
10. It provides an easy way to grow a linked list dynamically.
*/

3. Singly Linked List: Delete Node at the Beginning


#include <stdio.h>
#include <stdlib.h>

// Definition of the Node structure


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

// Function to delete a node from the beginning of the list


void deleteAtBeginning(struct Node** head) {
if (*head == NULL) {
printf("List is empty.\n");
return; // If the list is empty, return
}
struct Node* temp = *head; // Store the current head
*head = temp->next; // Update the head to the next node
free(temp); // Free the old head node
}

// Function to display the linked list


void display(struct Node* head) {
while (head != NULL) {
printf("%d -> ", head->data); // Print the current node's data
head = head->next; // Move to the next node
}
printf("NULL\n");
}

int main() {
struct Node* head = NULL; // Initialize the head to NULL
head = (struct Node*)malloc(sizeof(struct Node)); // Create a new node
head->data = 10;
head->next = NULL;

deleteAtBeginning(&head); // Delete the first node


display(head); // Display the list
return 0;
}

/* Explanation:
1. The `deleteAtBeginning` function removes the first node of the list.
2. If the list is empty, a message is printed and the function returns.
3. The current head is stored in `temp`, and the head is updated to the next
node.
4. The old head node is freed from memory.
5. The `display` function traverses the list and prints each node's data.
6. In `main`, a node with data 10 is created and then deleted.
7. After deletion, the list becomes empty, so "NULL" is displayed.
8. This operation reduces the size of the list by one node from the front.
9. It's useful when removing elements from the start is needed.
10. It demonstrates the simplicity of deleting nodes from a singly linked
list.
*/

4. Singly Linked List: Delete Node at the End


#include <stdio.h>
#include <stdlib.h>

// Definition of the Node structure


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

// Function to delete a node from the end of the list


void deleteAtEnd(struct Node** head) {
if (*head == NULL) {
printf("List is empty.\n");
return; // If the list is empty, return
}
struct Node* temp = *head;
if (temp->next == NULL) {
free(temp); // If there's only one node, free it
*head = NULL; // Update the head to NULL
return;
}
while (temp->next->next != NULL) {
temp = temp->next; // Traverse to the second-last node
}
free(temp->next); // Free the last node
temp->next = NULL; // Set the second-last node's next to NULL
}

// Function to display the linked list


void display(struct Node* head) {
while (head != NULL) {
printf("%d -> ", head->data); // Print the current node's data
head = head->next; // Move to the next node
}
printf("NULL\n");
}

int main() {
struct Node* head = NULL;
head = (struct Node*)malloc(sizeof(struct Node)); // Create the head node
head->data = 10;
head->next = NULL;
insertAtEnd(&head, 20); // Insert 20 at the end
deleteAtEnd(&head); // Delete the last node
display(head); // Display the list
return 0;
}

/* Explanation:
1. The `deleteAtEnd` function removes the last node in the list.
2. If the list is empty, a message is printed, and the function returns.
3. If there’s only one node, it’s freed and the head is set to NULL.
4. Otherwise, the program traverses the list to find the second-last node.
5. The last node is freed and the second-last node's `next` pointer is set to
NULL.
6. The `display` function prints the list from the head node to the last
node.
7. In `main`, the list starts with one node and another is appended.
8. After deleting the last node, the list is displayed as "10 -> NULL".
9. This operation reduces the list size by removing the last node.
10. It's an efficient way to remove elements from the end of a singly linked
list.
*/

5. Singly Linked List: Search for an Element


#include <stdio.h>
#include <stdlib.h>

// Definition of the Node structure


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

// Function to search for an element in the list


int search(struct Node* head, int key) {
while (head != NULL) {
if (head->data == key) {
return 1; // If the element is found, return 1
}
head = head->next; // Move to the next node
}
return 0; // If the element is not found, return 0
}

// Function to display the linked list


void display(struct Node* head) {
while (head != NULL) {
printf("%d -> ", head->data); // Print the current node's data
head = head->next; // Move to the next node
}
printf("NULL\n");
}

int main() {
struct Node* head = NULL;
head = (struct Node*)malloc(sizeof(struct Node)); // Create the head node
head->data = 10;
head->next = NULL;

if (search(head, 10)) {
printf("Element found.\n");
} else {
printf("Element not found.\n");
}

return 0;
}

/* Explanation:
1. The `search` function looks for a specific element in the list.
2. It iterates over each node in the list.
3. If the node's `data` matches the `key`, the function returns 1.
4. If the list is traversed completely without finding the key, it returns 0.
5. In `main`, the list is initialized with a single node containing data 10.
6. The `search` function is called to check if
the value 10 exists in the list.
7. The result is printed based on whether the element is found or not.
8. In this case, the element is found and "Element found." is printed.
9. This demonstrates how to search for an element in a singly linked list.
10. Searching can be used in applications that need to find specific data in
a list. */

6. Singly Linked List: Reverse the List


#include <stdio.h>
#include <stdlib.h>

// Definition of the Node structure


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

// Function to reverse the list


void reverse(struct Node** head) {
struct Node *prev = NULL, *current = *head, *next = NULL;

// Traverse the list and reverse the links


while (current != NULL) {
next = current->next; // Store the next node
current->next = prev; // Reverse the current node's pointer
prev = current; // Move prev to the current node
current = next; // Move current to the next node
}
*head = prev; // Set the head to the new first node (previously last)
}

// Function to display the linked list


void display(struct Node* head) {
while (head != NULL) {
printf("%d -> ", head->data); // Print the current node's data
head = head->next; // Move to the next node
}
printf("NULL\n");
}

int main() {
struct Node* head = NULL;
head = (struct Node*)malloc(sizeof(struct Node)); // Create the head node
head->data = 10;
head->next = NULL;

insertAtEnd(&head, 20); // Insert 20 at the end


insertAtEnd(&head, 30); // Insert 30 at the end
reverse(&head); // Reverse the list
display(head); // Display the reversed list
return 0;
}

/* Explanation:
1. The `reverse` function reverses the entire linked list.
2. We use three pointers: `prev`, `current`, and `next`.
3. Traverse the list, updating each node's `next` pointer to point to the
previous node.
4. At the end of the loop, `prev` points to the new head of the list.
5. The `display` function prints the list from head to tail.
6. In `main`, three nodes are inserted into the list, and the list is
reversed.
7. After reversal, the list is displayed in reverse order as "30 -> 20 -> 10
-> NULL".
8. This operation changes the list from the original order to the opposite.
9. Reversing the list can be helpful in various scenarios like undo
operations.
10. The logic demonstrates the fundamental algorithm of reversing a singly
linked list.
*/

7. Singly Linked List: Find the Length of the List


#include <stdio.h>
#include <stdlib.h>

// Definition of the Node structure


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

// Function to calculate the length of the list


int length(struct Node* head) {
int len = 0;
while (head != NULL) {
len++; // Increment the length for each node
head = head->next; // Move to the next node
}
return len; // Return the length of the list
}

// Function to display the linked list


void display(struct Node* head) {
while (head != NULL) {
printf("%d -> ", head->data); // Print the current node's data
head = head->next; // Move to the next node
}
printf("NULL\n");
}

int main() {
struct Node* head = NULL;
head = (struct Node*)malloc(sizeof(struct Node)); // Create the head node
head->data = 10;
head->next = NULL;

insertAtEnd(&head, 20); // Insert 20 at the end


insertAtEnd(&head, 30); // Insert 30 at the end

printf("Length of the list: %d\n", length(head)); // Print the length of


the list
return 0;
}

/* Explanation:
1. The `length` function calculates the total number of nodes in the list.
2. It starts with a length of 0 and traverses the list, incrementing the
length for each node.
3. The `display` function is used to print the list for visualization.
4. In `main`, a few nodes are inserted into the list.
5. The `length` function is called to print the number of nodes in the list.
6. The result will be the length of the list, which is 3 in this case.
7. This operation is useful when determining the size of a linked list.
8. The length of the list can also be used to validate list integrity.
9. This logic helps in scenarios where we need to process nodes based on
their count.
10. The function runs in O(n) time complexity where n is the number of nodes.
*/

8. Doubly Linked List: Insert Node at the Beginning


#include <stdio.h>
#include <stdlib.h>

// Definition of the Node structure


struct Node {
int data;
struct Node* next;
struct Node* prev;
};

// Function to insert a node at the beginning of the doubly linked list


void insertAtBeginning(struct Node** head, int data) {
struct Node* newNode = (struct Node*)malloc(sizeof(struct Node)); //
Create a new node
newNode->data = data; // Set the data for the new node
newNode->next = *head; // Link the new node to the current head

if (*head != NULL) {
(*head)->prev = newNode; // Update the previous pointer of the old
head
}
*head = newNode; // Update the head to the new node
}

// Function to display the doubly linked list


void display(struct Node* head) {
while (head != NULL) {
printf("%d <-> ", head->data); // Print the current node's data
head = head->next; // Move to the next node
}
printf("NULL\n");
}

int main() {
struct Node* head = NULL; // Initialize the head to NULL
insertAtBeginning(&head, 10); // Insert 10 at the beginning
insertAtBeginning(&head, 20); // Insert 20 at the beginning
insertAtBeginning(&head, 30); // Insert 30 at the beginning
display(head); // Display the list
return 0;
}

/* Explanation:
1. The `insertAtBeginning` function inserts a new node at the start of the
doubly linked list.
2. A new node is created and linked to the current head, and its `prev`
pointer is set to NULL.
3. If the list is not empty, the previous head's `prev` pointer is updated to
point to the new node.
4. The head is updated to the new node, making it the first node in the list.
5. The `display` function prints the list from head to tail, with the "prev"
pointers showing the reverse order.
6. In `main`, three nodes are inserted into the list at the beginning.
7. The resulting list is displayed as "30 <-> 20 <-> 10 <-> NULL".
8. This operation adds nodes at the beginning, moving them to the front.
9. It is useful when inserting elements in a deque-like structure.
10. The time complexity of this operation is O(1) since no traversal is
needed.
*/

9. Doubly Linked List: Insert Node at the End


#include <stdio.h>
#include <stdlib.h>

// Definition of the Node structure


struct Node {
int data;
struct Node* next;
struct Node* prev;
};

// Function to insert a node at the end of the doubly linked list


void insertAtEnd(struct Node** head, int data) {
struct Node* newNode = (struct Node*)malloc(sizeof(struct Node)); //
Create a new node
struct Node* temp = *head; // Temporary pointer to traverse the list
newNode->data = data; // Set the data for the new node
newNode->next = NULL; // Set the next pointer of the new node to NULL

if (*head == NULL) {
*head = newNode; // If the list is empty, the new node becomes the
head
newNode->prev = NULL;
return;
}

while (temp->next != NULL) {


temp = temp->next; // Traverse to the last node
}
temp->next = newNode; // Link the last node to the new node
newNode->prev = temp; // Set the new node's previous pointer to the last
node
}

// Function to display the doubly linked list


void display(struct Node* head) {
while (head != NULL) {
printf("%d <-> ", head->data); // Print the current node's data
head = head->next; // Move to the next node
}
printf("NULL\n");
}

int main() {
struct Node* head = NULL; // Initialize the head to NULL
insertAtEnd(&head, 10); // Insert 10 at the end
insertAtEnd(&head, 20); // Insert 20 at the end
insertAtEnd(&head, 30); // Insert 30 at the end
display(head); // Display the list
return 0;
}

/* Explanation:
1. The `insertAtEnd` function adds a new node at the end of the doubly linked
list.
2. A new node is created, its `next` pointer is set to NULL, and it is linked
to the last node.
3. If the list is empty, the new node becomes the head, and its `prev`
pointer is set to NULL.
4. Otherwise, the program traverses the list to find the last node, then
appends the new node.
5. The `prev` pointer of the new node is set to the last node, maintaining
the doubly linked structure.
6. The `display` function prints the list from head to tail.
7. In `main`, three nodes are inserted into the list at the end.
8. The resulting list is displayed as "10 <-> 20 <-> 30 <-> NULL".
9. This operation ensures nodes are inserted at the end, preserving the list
order.
10. It demonstrates how to grow a doubly linked list dynamically with
efficient insertion at the end.
*/

10. Circular Linked List: Insert Node at the Beginning


#include <stdio.h>
#include <stdlib.h>

// Definition of the Node structure


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

// Function to insert a node at the beginning of the circular linked list


void insertAtBeginning(struct Node** head, int data) {
struct Node* newNode = (struct Node*)malloc(sizeof(struct Node)); //
Create a new node
newNode->data = data; // Set the data for the new node
if (*head == NULL) {
*head = newNode; // If the list is empty, the new node becomes the
head
newNode->next = *head; // Point the next of the new node to itself
} else {
struct Node* temp = *head;
while (temp->next != *head) { // Traverse to the last node
temp = temp->next;
}
temp->next = newNode; // Link the last node to the new node
newNode->next = *head; // Point the new node to the head
*head = newNode; // Update the head to the new node
}
}

// Function to display the circular linked list


void display(struct Node* head) {
if (head == NULL) {
printf("List is empty.\n");
return;
}
struct Node* temp = head;
do {
printf("%d -> ", temp->data); // Print the current node's data
temp = temp->next; // Move to the next node
} while (temp != head); // Stop when we reach the head node again
printf("(back to head)\n");
}

int main() {
struct Node* head = NULL; // Initialize the head to NULL
insertAtBeginning(&head, 10); // Insert 10 at the beginning
insertAtBeginning(&head, 20); // Insert 20 at the beginning
insertAtBeginning(&head, 30); // Insert 30 at the beginning
display(head); // Display the circular list
return 0;
}

/* Explanation:
1. The `insertAtBeginning` function inserts a node at the beginning of a
circular linked list.
2. If the list is empty, the new node becomes the head and points to itself,
forming a loop.
3. If the list is not empty, the program traverses to the last node and links
it to the new node.
4. The new node’s `next` pointer is set to the head, completing the circular
structure.
5. The `display` function traverses the list starting from the head, printing
each node.
6. In `main`, three nodes are inserted at the beginning of the list.
7. The resulting list is displayed as "30 -> 20 -> 10 -> (back to head)".
8. The program demonstrates how circular references are handled in the list.
9. Circular linked lists are useful for applications like buffering and
round-robin scheduling.
10. The time complexity for this operation is O(1) for inserting at the
beginning of the list.
*/

11. Circular Linked List: Insert Node at the End


#include <stdio.h>
#include <stdlib.h>

// Definition of the Node structure


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

// Function to insert a node at the end of a circular linked list


void insertAtEnd(struct Node** head, int data) {
struct Node* newNode = (struct Node*)malloc(sizeof(struct Node)); //
Create a new node
struct Node* temp = *head; // Temporary pointer to traverse the list
newNode->data = data; // Set the data for the new node

if (*head == NULL) {
*head = newNode; // If the list is empty, make the new node the head
newNode->next = *head; // The new node points to itself (circular)
} else {
while (temp->next != *head) {
temp = temp->next; // Traverse to the last node
}
temp->next = newNode; // Link the last node to the new node
newNode->next = *head; // The new node points back to the head
}
}

// Function to display the circular linked list


void display(struct Node* head) {
if (head == NULL) {
printf("List is empty.\n");
return;
}
struct Node* temp = head;
do {
printf("%d -> ", temp->data); // Print the current node's data
temp = temp->next; // Move to the next node
} while (temp != head); // Stop when we reach the head node again
printf("(back to head)\n");
}

int main() {
struct Node* head = NULL; // Initialize the head to NULL
insertAtEnd(&head, 10); // Insert 10 at the end
insertAtEnd(&head, 20); // Insert 20 at the end
insertAtEnd(&head, 30); // Insert 30 at the end
display(head); // Display the circular list
return 0;
}

/* Explanation:
1. The `insertAtEnd` function adds a new node at the end of a circular linked
list.
2. If the list is empty, the new node becomes the head and points to itself.
3. If the list is not empty, the program traverses to the last node and links
it to the new node.
4. The new node’s `next` pointer is set to the head, ensuring the list
remains circular.
5. The `display` function prints the list starting from the head, then
circles back to the head.
6. In `main`, three nodes are inserted at the end of the list.
7. The resulting list is displayed as "10 -> 20 -> 30 -> (back to head)".
8. This operation efficiently adds nodes to the end of a circular list
without needing a full traversal for insertion.
9. Circular linked lists are useful in applications where traversal needs to
wrap around (e.g., a round-robin scheduler).
10. The time complexity for this operation is O(n) for traversal, but O(1)
for insertion once the last node is found.
*/

12. Circular Linked List: Delete Node at the Beginning


#include <stdio.h>
#include <stdlib.h>

// Definition of the Node structure


struct Node {
int data;
struct Node* next;
};
// Function to delete the node at the beginning of a circular linked list
void deleteAtBeginning(struct Node** head) {
if (*head == NULL) {
printf("List is empty.\n");
return;
}
struct Node* temp = *head;
if (temp->next == *head) { // If there is only one node
free(temp); // Free the node
*head = NULL; // Set the head to NULL
} else {
// Traverse to the last node to update its next pointer
struct Node* last = *head;
while (last->next != *head) {
last = last->next;
}
*head = temp->next; // Move the head to the next node
last->next = *head; // Update the last node to point to the new head
free(temp); // Free the old head node
}
}

// Function to display the circular linked list


void display(struct Node* head) {
if (head == NULL) {
printf("List is empty.\n");
return;
}
struct Node* temp = head;
do {
printf("%d -> ", temp->data); // Print the current node's data
temp = temp->next; // Move to the next node
} while (temp != head); // Stop when we reach the head node again
printf("(back to head)\n");
}

int main() {
struct Node* head = NULL; // Initialize the head to NULL
insertAtEnd(&head, 10); // Insert 10 at the end
insertAtEnd(&head, 20); // Insert 20 at the end
insertAtEnd(&head, 30); // Insert 30 at the end
display(head); // Display the list
deleteAtBeginning(&head); // Delete the first node
display(head); // Display the list after deletion
return 0;
}

/* Explanation:
1. The `deleteAtBeginning` function deletes the first node in the circular
linked list.
2. If the list is empty, the function simply returns.
3. If there is only one node, it is freed, and the head is set to NULL.
4. If there are multiple nodes, the program finds the last node and updates
its `next` pointer to the new head.
5. The head is updated to the next node, and the old head node is freed.
6. The `display` function prints the list starting from the head and then
circles back to the head.
7. In `main`, three nodes are inserted at the end of the list, and the first
node is deleted.
8. The resulting list after deletion is displayed as "20 -> 30 -> (back to
head)".
9. Deleting from the beginning of a circular list requires updating the last
node’s pointer.
10. The time complexity of this operation is O(n) due to the traversal to
find the last node.
*/

13. Doubly Linked List: Delete Node at the Beginning


#include <stdio.h>
#include <stdlib.h>

// Definition of the Node structure


struct Node {
int data;
struct Node* next;
struct Node* prev;
};

// Function to delete the node at the beginning of the doubly linked list
void deleteAtBeginning(struct Node** head) {
if (*head == NULL) {
printf("List is empty.\n");
return;
}
struct Node* temp = *head;
if (temp->next == NULL) { // If there is only one node
free(temp);
*head = NULL; // Set the head to NULL
} else {
*head = temp->next; // Move the head to the next node
(*head)->prev = NULL; // Update the new head's previous pointer
free(temp); // Free the old head node
}
}

// Function to display the doubly linked list


void display(struct Node* head) {
while (head != NULL) {
printf("%d <-> ", head->data); // Print the current node's data
head = head->next; // Move to the next node
}
printf("NULL\n");
}

int main() {
struct Node* head = NULL; // Initialize the head to NULL
insertAtBeginning(&head, 10); // Insert 10 at the beginning
insertAtBeginning(&head, 20); // Insert 20 at the beginning
insertAtBeginning(&head, 30); // Insert 30 at the beginning
display(head); // Display the list
deleteAtBeginning(&head); // Delete the first node
display(head); // Display the list after deletion
return 0;
}

/* Explanation:
1. The `deleteAtBeginning` function removes the first node from a doubly
linked list.
2. If the list is empty, a message is printed, and the function returns.
3. If there is only one node, it is freed, and the head is set to NULL.
4. If there are multiple nodes, the head is updated to the next node.
5. The new head's `prev` pointer is set to NULL.
6. The `display` function prints the list starting from the head node.
7. In `main`, three nodes are inserted at the beginning, and the first node
is deleted.
8. The resulting list after deletion is displayed as "20 <-> 10 <-> NULL".
9. Deleting the first node from a doubly linked list is efficient since the
previous node of the new head is updated.
10. The time complexity of this operation is O(1), making it efficient even
for large lists.
*/

14. Doubly Linked List: Delete Node at the End


#include <stdio.h>
#include <stdlib.h>

// Definition of the Node structure


struct Node {
int data;
struct Node* next;
struct Node* prev;
};

// Function to delete the node at the end of the doubly linked list
void deleteAtEnd(struct Node** head) {
if (*head == NULL) {
printf("List is empty.\n");
return;
}
struct Node* temp = *head;
if (temp->next == NULL) { // If there is only one node
free(temp);
*head = NULL; // Set the head to NULL
} else {
while (temp->next != NULL) { // Traverse to the last node
temp = temp->next;
}
temp->prev->next = NULL; // Update the second-last node’s next
pointer to NULL
free(temp); // Free the last node
}
}

// Function to display the doubly linked list


void display(struct Node* head) {
while (head != NULL) {
printf("%d <-> ", head->data); // Print the current node's data
head = head->next; // Move to the next node
}
printf("NULL\n");
}

int main() {
struct Node* head = NULL; // Initialize the head to NULL
insertAtEnd(&head, 10); // Insert 10 at the end
insertAtEnd(&head, 20); // Insert 20 at the end
insertAtEnd(&head, 30); // Insert 30 at the end
display(head); // Display the list
deleteAtEnd(&head); // Delete the last node
display(head); // Display the list after deletion
return 0;
}

/* Explanation:
1. The `deleteAtEnd` function removes the last node from a doubly linked
list.
2. If the list is empty, a message is printed, and the function returns.
3. If there is only one node, it is freed, and the head is set to NULL.
4. If there are multiple nodes, the program traverses the list to find the
last node.
5. The second-last node's `next` pointer is set to NULL, and the last node is
freed.
6. The `display` function prints the list from head to tail.
7. In `main`, three nodes are inserted at the end, and the last node is
deleted.
8. The resulting list after deletion is displayed as "10 <-> 20 <-> NULL".
9. This operation efficiently removes the last node from the list, updating
the second-last node's next pointer.
10. The time complexity is O(n) for traversal to find the last node, but the
operation is still efficient for typical use cases. */

15. Singly Linked List: Delete a Specific Node


#include <stdio.h>
#include <stdlib.h>

// Definition of the Node structure


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

// Function to delete a specific node from the singly linked list


void deleteNode(struct Node** head, int key) {
struct Node* temp = *head;
struct Node* prev = NULL;

// If the node to be deleted is the head node


if (temp != NULL && temp->data == key) {
*head = temp->next; // Move the head to the next node
free(temp); // Free the old head
return;
}

// Search for the node to be deleted


while (temp != NULL && temp->data != key) {
prev = temp;
temp = temp->next;
}

// If the key was not found


if (temp == NULL) return;

// Unlink the node from the list


prev->next = temp->next;
free(temp); // Free the node
}

// Function to display the linked list


void display(struct Node* head) {
while (head != NULL) {
printf("%d -> ", head->data);
head = head->next;
}
printf("NULL\n");
}

int main() {
struct Node* head = NULL;
insertAtEnd(&head, 10);
insertAtEnd(&head, 20);
insertAtEnd(&head, 30);
insertAtEnd(&head, 40);

printf("Original List: ");


display(head);

deleteNode(&head, 20); // Delete node with value 20

printf("List after deleting 20: ");


display(head);
return 0;
}

/* Explanation:
1. The `deleteNode` function deletes the first occurrence of a specific node
(with value `key`).
2. If the node to be deleted is the head node, the head is updated to the
next node, and the old head is freed.
3. If the node to be deleted is not the head, the function traverses the list
to find the node.
4. Once found, the previous node’s `next` pointer is updated to bypass the
node to be deleted.
5. The `display` function prints the list from head to tail.
6. In `main`, a few nodes are inserted, and then a node with value 20 is
deleted.
7. The resulting list after deletion is displayed as "10 -> 30 -> 40 ->
NULL".
8. Deleting a specific node requires traversal of the list, which makes the
time complexity O(n).
9. The logic is useful in applications that require deletion of specific data
from a list.
10. This operation demonstrates typical deletion from a singly linked list.
*/

16. Circular Linked List: Delete Node by Key


#include <stdio.h>
#include <stdlib.h>

// Definition of the Node structure


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

// Function to delete a node by its value in a circular linked list


void deleteNodeByKey(struct Node** head, int key) {
if (*head == NULL) {
printf("List is empty.\n");
return;
}

struct Node *temp = *head, *prev = NULL;

// If the node to be deleted is the head node


if (temp != NULL && temp->data == key) {
// Find the last node to update its next pointer
struct Node* last = *head;
while (last->next != *head) {
last = last->next;
}

if (temp->next == *head) { // If there is only one node


free(temp);
*head = NULL;
} else {
*head = temp->next; // Update head to the next node
last->next = *head; // Update the last node to point to the new
head
free(temp);
}
return;
}

// Search for the node to delete


while (temp->next != *head && temp->data != key) {
prev = temp;
temp = temp->next;
}

// If the key was not found


if (temp == *head) return;

// Unlink the node from the list


prev->next = temp->next;
free(temp);
}

// Function to display the circular linked list


void display(struct Node* head) {
if (head == NULL) {
printf("List is empty.\n");
return;
}

struct Node* temp = head;


do {
printf("%d -> ", temp->data);
temp = temp->next;
} while (temp != head);
printf("(back to head)\n");
}

int main() {
struct Node* head = NULL;
insertAtEnd(&head, 10);
insertAtEnd(&head, 20);
insertAtEnd(&head, 30);
insertAtEnd(&head, 40);

printf("Original Circular List: ");


display(head);

deleteNodeByKey(&head, 30); // Delete node with value 30

printf("Circular List after deleting 30: ");


display(head);
return 0;
}

/* Explanation:
1. The `deleteNodeByKey` function deletes a node from the circular linked
list by its value (`key`).
2. If the node to be deleted is the head, the head pointer is updated, and
the last node's `next` pointer is adjusted.
3. If the node is not the head, the program searches for the node to be
deleted.
4. Once found, the previous node's `next` pointer is updated to skip the node
to be deleted.
5. The `display` function prints the list from head to tail, looping back to
the head due to the circular structure.
6. In `main`, nodes are inserted, and a node with value 30 is deleted.
7. The resulting circular list after deletion is displayed as "10 -> 20 -> 40
-> (back to head)".
8. Deleting a node requires handling both the circular nature and node
unlinking carefully.
9. This operation demonstrates efficient node deletion from circular linked
lists.
10. The time complexity for this operation is O(n), where n is the number of
nodes in the list.
*/

17. Singly Linked List: Delete the Last Node


#include <stdio.h>
#include <stdlib.h>

// Definition of the Node structure


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

// Function to delete the last node from the singly linked list
void deleteAtEnd(struct Node** head) {
if (*head == NULL) {
printf("List is empty.\n");
return;
}

struct Node* temp = *head;


struct Node* prev = NULL;

// If there is only one node


if (temp->next == NULL) {
free(temp);
*head = NULL; // Set the head to NULL
return;
}

// Traverse to the last node


while (temp->next != NULL) {
prev = temp;
temp = temp->next;
}

// Unlink the last node


prev->next = NULL;
free(temp);
}

// Function to display the linked list


void display(struct Node* head) {
while (head != NULL) {
printf("%d -> ", head->data);
head = head->next;
}
printf("NULL\n");
}

int main() {
struct Node* head = NULL;
insertAtEnd(&head, 10);
insertAtEnd(&head, 20);
insertAtEnd(&head, 30);
insertAtEnd(&head, 40);

printf("Original List: ");


display(head);

deleteAtEnd(&head); // Delete the last node

printf("List after deleting the last node: ");


display(head);
return 0;
}

/* Explanation:
1. The `deleteAtEnd` function deletes the last node of a singly linked list.
2. If the list is empty, a message is printed and the function returns.
3. If there is only one node, it is freed, and the head is set to NULL.
4. For lists with more than one node, the program traverses to the last node
and updates the second-last node’s `next` pointer to NULL.
5. The `display` function prints the list from head to tail.
6. In `main`, nodes are inserted into the list, and the last node is deleted.
7. The resulting list after deletion is displayed as "10 -> 20 -> 30 ->
NULL".
8. Deleting the last node involves finding the penultimate node and updating
the next pointer.
9. This operation is commonly used when removing elements from the end of a
list.
10. The time complexity for this operation is O(n) because it requires
traversal to find the last node.
*/

18. Doubly Linked List: Delete Node by Value


#include <stdio.h>
#include <stdlib.h>

// Definition of the Node structure


struct Node {
int data;
struct Node* next;
struct Node* prev;
};

// Function to delete a node by value in a doubly linked list


void deleteNodeByValue(struct Node** head, int key) {
struct Node* temp = *head;

// If the list is empty


if (*head == NULL) {
printf("List is empty.\n");
return;
}

// Traverse the list to find the node to delete


while (temp != NULL && temp->data != key) {
temp = temp->next;
}

// If the node is not found


if (temp == NULL) return;

// If the node to be deleted is the head


if (temp == *head) {
*head = temp->next;
if (*head != NULL) {
(*head)->prev = NULL;
}
free(temp);
return;
}

// If the node to be deleted is in the middle or end


if (temp->next != NULL) {
temp->next->prev = temp->prev;
}
if (temp->prev != NULL) {
temp->prev->next = temp->next;
}

free(temp);
}

// Function to display the doubly linked list


void display(struct Node* head) {
while (head != NULL) {
printf("%d <-> ", head->data);
head = head->next;
}
printf("NULL\n");
}

int main() {
struct Node* head = NULL;
insertAtEnd(&head, 10);
insertAtEnd(&head, 20);
insertAtEnd(&head, 30);
insertAtEnd(&head, 40);

printf("Original Doubly Linked List: ");


display(head);

deleteNodeByValue(&head, 30); // Delete node with value 30

printf("List after deleting 30: ");


display(head);
return 0;
}

/* Explanation:
1. The `deleteNodeByValue` function deletes a node by its value in a doubly
linked list.
2. If the list is empty, a message is printed, and the function returns.
3. The program traverses the list to find the node with the specified value
(`key`).
4. Once found, the program updates the previous and next pointers of the
surrounding nodes.
5. If the node to be deleted is the head, the head pointer is updated, and
its previous pointer is set to NULL.
6. The `display` function prints the list from head to tail.
7. In `main`, nodes are inserted, and a node with value 30 is deleted.
8. The resulting list after deletion is displayed as "10 <-> 20 <-> 40 <->
NULL".
9. Deletion in a doubly linked list requires careful updating of both the
`next` and `prev` pointers.
10. This operation is O(1) if the node is already located, but O(n) for
searching.
*/

19. Circular Linked List: Reverse the List


#include <stdio.h>
#include <stdlib.h>

// Definition of the Node structure


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

// Function to reverse a circular linked list


void reverse(struct Node** head) {
if (*head == NULL) {
return; // If the list is empty, no need to reverse
}

struct Node *prev = NULL, *curr = *head, *next = NULL;


struct Node *last = *head;

// Traverse to find the last node


while (last->next != *head) {
last = last->next;
}

// Reverse the list


do {
next = curr->next;
curr->next = prev;
prev = curr;
curr = next;
} while (curr != *head);

// Update the head and the last node's next pointer


*head = prev;
last->next = *head; // Point the last node to the new head
}
// Function to display the circular linked list
void display(struct Node* head) {
if (head == NULL) {
printf("List is empty.\n");
return;
}
struct Node* temp = head;
do {
printf("%d -> ", temp->data);
temp = temp->next;
} while (temp != head);
printf("(back to head)\n");
}

int main() {
struct Node* head = NULL;
insertAtEnd(&head, 10);
insertAtEnd(&head, 20);
insertAtEnd(&head, 30);
insertAtEnd(&head, 40);

printf("Original Circular List: ");


display(head);

reverse(&head); // Reverse the list

printf("Reversed Circular List: ");


display(head);
return 0;
}

/* Explanation:
1. The `reverse` function reverses the circular linked list by reversing the
`next` pointers.
2. The program finds the last node in the list to ensure the circular
structure is preserved.
3. The list is reversed by iterating through the nodes and updating the
`next` pointers.
4. Once reversed, the head is updated, and the last node's `next` pointer is
updated to point to the new head.
5. The `display` function prints the list from head to tail, looping back to
the head.
6. In `main`, the list is displayed before and after the reversal.
7. The resulting list after reversal is displayed as "40 -> 30 -> 20 -> 10 ->
(back to head)".
8. Reversing the list in a circular manner requires updating the head and the
last node’s `next`.
9. The time complexity for this operation is O(n), where n is the number of
nodes in the list.
10. This operation demonstrates reversing a circular linked list efficiently.
*/

20. Singly Linked List: Merge Two Sorted Lists


#include <stdio.h>
#include <stdlib.h>
// Definition of the Node structure
struct Node {
int data;
struct Node* next;
};

// Function to merge two sorted linked lists


struct Node* mergeSortedLists(struct Node* list1, struct Node* list2) {
struct Node* result = NULL;

// Base cases
if (list1 == NULL) return list2;
if (list2 == NULL) return list1;

// Recursive merging process


if (list1->data <= list2->data) {
result = list1;
result->next = mergeSortedLists(list1->next, list2);
} else {
result = list2;
result->next = mergeSortedLists(list1, list2->next);
}
return result;
}

// Function to display the linked list


void display(struct Node* head) {
while (head != NULL) {
printf("%d -> ", head->data);
head = head->next;
}
printf("NULL\n");
}

int main() {
struct Node* list1 = NULL;
struct Node* list2 = NULL;

// Create two sorted lists


insertAtEnd(&list1, 10);
insertAtEnd(&list1, 20);
insertAtEnd(&list1, 30);

insertAtEnd(&list2, 5);
insertAtEnd(&list2, 15);
insertAtEnd(&list2, 25);

printf("List 1: ");
display(list1);
printf("List 2: ");
display(list2);

struct Node* mergedList = mergeSortedLists(list1, list2); // Merge the


sorted lists

printf("Merged List: ");


display(mergedList);
return 0;
}

/* Explanation:
1. The `mergeSortedLists` function merges two sorted singly linked lists into
a single sorted list.
2. The base cases handle the scenario when either list is empty.
3. The function recursively compares the head elements of both lists and
links the smaller element to the result.
4. The merging process ensures that the resulting list is sorted by always
picking the smaller element first.
5. The `display` function prints the merged list from head to tail.
6. In `main`, two sorted lists are created and merged using the function.
7. The merged list is displayed as "5 -> 10 -> 15 -> 20 -> 25 -> 30 -> NULL".
8. This method takes advantage of recursion to merge the two sorted lists.
9. The time complexity of this operation is O(n + m), where n and m are the
lengths of the two lists.
10. This operation demonstrates how to merge two sorted linked lists
efficiently.
*/

You might also like