Doubly Linked List in C (Full Implementation)
#include <stdio.h>
#include <stdlib.h>
// Define node using typedef
typedef struct Node {
int data;
struct Node* prev;
struct Node* next;
} Node;
// --- Function Declarations ---
Node* createNode(int value);
void insertAtFirst(Node** head, Node** tail, Node* newNode);
void insertAtLast(Node** head, Node** tail, Node* newNode);
void insertAfter(Node** head, Node** tail, int value, Node* newNode);
void insertBefore(Node** head, Node** tail, int value, Node* newNode);
void deleteAtFirst(Node** head, Node** tail);
void deleteAtLast(Node** head, Node** tail);
void deleteAfter(Node** head, Node** tail, int value);
void deleteBefore(Node** head, Node** tail, int value);
void searchNode(Node* head, int value);
void reverseList(Node** head, Node** tail);
void displayForward(Node* head);
void displayBackward(Node* tail);
// --- Function Definitions ---
// Create a new node
Node* createNode(int value) {
Node* newNode = (Node*)malloc(sizeof(Node));
newNode->data = value;
newNode->prev = NULL;
newNode->next = NULL;
return newNode;
}
// Insert at first
void insertAtFirst(Node** head, Node** tail, Node* newNode) {
if (*head == NULL) {
*head = *tail = newNode;
return;
}
newNode->next = *head;
(*head)->prev = newNode;
*head = newNode;
}
// Insert at last
void insertAtLast(Node** head, Node** tail, Node* newNode) {
if (*tail == NULL) {
*head = *tail = newNode;
return;
}
(*tail)->next = newNode;
newNode->prev = *tail;
*tail = newNode;
}
// Insert after given node
void insertAfter(Node** head, Node** tail, int value, Node* newNode) {
Node* temp = *head;
while (temp != NULL && temp->data != value) {
temp = temp->next;
}
if (temp == NULL) {
printf("Node %d not found\n", value);
free(newNode);
return;
}
newNode->next = temp->next;
newNode->prev = temp;
if (temp->next != NULL)
temp->next->prev = newNode;
else
*tail = newNode; // inserted at last
temp->next = newNode;
}
// Insert before given node
void insertBefore(Node** head, Node** tail, int value, Node* newNode) {
Node* temp = *head;
while (temp != NULL && temp->data != value) {
temp = temp->next;
}
if (temp == NULL) {
printf("Node %d not found\n", value);
free(newNode);
return;
}
newNode->next = temp;
newNode->prev = temp->prev;
if (temp->prev != NULL)
temp->prev->next = newNode;
else
*head = newNode; // inserted before head
temp->prev = newNode;
}
// Delete at first
void deleteAtFirst(Node** head, Node** tail) {
if (*head == NULL) {
printf("List is empty\n");
return;
}
Node* temp = *head;
if (*head == *tail) {
*head = *tail = NULL;
} else {
*head = (*head)->next;
(*head)->prev = NULL;
}
free(temp);
}
// Delete at last
void deleteAtLast(Node** head, Node** tail) {
if (*tail == NULL) {
printf("List is empty\n");
return;
}
Node* temp = *tail;
if (*head == *tail) {
*head = *tail = NULL;
} else {
*tail = (*tail)->prev;
(*tail)->next = NULL;
}
free(temp);
}
// Delete after given node
void deleteAfter(Node** head, Node** tail, int value) {
Node* temp = *head;
while (temp != NULL && temp->data != value) {
temp = temp->next;
}
if (temp == NULL || temp->next == NULL) {
printf("No node exists after %d\n", value);
return;
}
Node* delNode = temp->next;
temp->next = delNode->next;
if (delNode->next != NULL)
delNode->next->prev = temp;
else
*tail = temp; // deleted last node
free(delNode);
}
// Delete before given node
void deleteBefore(Node** head, Node** tail, int value) {
Node* temp = *head;
while (temp != NULL && temp->data != value) {
temp = temp->next;
}
if (temp == NULL || temp->prev == NULL) {
printf("No node exists before %d\n", value);
return;
}
Node* delNode = temp->prev;
if (delNode->prev != NULL) {
delNode->prev->next = temp;
temp->prev = delNode->prev;
} else {
*head = temp;
temp->prev = NULL;
}
free(delNode);
}
// Search for any node
void searchNode(Node* head, int value) {
Node* temp = head;
int pos = 1;
while (temp != NULL) {
if (temp->data == value) {
printf("Node %d found at position %d\n", value, pos);
return;
}
temp = temp->next;
pos++;
}
printf("Node %d not found\n", value);
}
// Reverse list
void reverseList(Node** head, Node** tail) {
Node* curr = *head;
Node* temp = NULL;
while (curr != NULL) {
temp = curr->prev;
curr->prev = curr->next;
curr->next = temp;
curr = curr->prev;
}
if (temp != NULL) {
*tail = *head;
*head = temp->prev;
}
}
// Display forward
void displayForward(Node* head) {
if (head == NULL) {
printf("List is empty\n");
return;
}
Node* temp = head;
while (temp != NULL) {
printf("%d <-> ", temp->data);
temp = temp->next;
}
printf("NULL\n");
}
// Display backward
void displayBackward(Node* tail) {
if (tail == NULL) {
printf("List is empty\n");
return;
}
Node* temp = tail;
while (temp != NULL) {
printf("%d <-> ", temp->data);
temp = temp->prev;
}
printf("NULL\n");
}
// --- Main function with menu ---
int main() {
Node* head = NULL;
Node* tail = NULL;
Node* newNode;
int choice, value, valAfter, valBefore;
while (1) {
printf("\n--- Doubly Linked List Menu ---\n");
printf("1. Insert at First\n");
printf("2. Insert at Last\n");
printf("3. Insert After Any Node\n");
printf("4. Insert Before Any Node\n");
printf("5. Delete at First\n");
printf("6. Delete at Last\n");
printf("7. Delete After Any Node\n");
printf("8. Delete Before Any Node\n");
printf("9. Search Any Node\n");
printf("10. Reverse List\n");
printf("11. Display Forward\n");
printf("12. Display Backward\n");
printf("13. Exit\n");
printf("Enter your choice: ");
scanf("%d", &choice);
switch (choice) {
case 1:
printf("Enter value: ");
scanf("%d", &value);
newNode = createNode(value);
insertAtFirst(&head, &tail, newNode);
break;
case 2:
printf("Enter value: ");
scanf("%d", &value);
newNode = createNode(value);
insertAtLast(&head, &tail, newNode);
break;
case 3:
printf("Enter node value after which to insert: ");
scanf("%d", &value);
printf("Enter new value: ");
scanf("%d", &valAfter);
newNode = createNode(valAfter);
insertAfter(&head, &tail, value, newNode);
break;
case 4:
printf("Enter node value before which to insert: ");
scanf("%d", &value);
printf("Enter new value: ");
scanf("%d", &valBefore);
newNode = createNode(valBefore);
insertBefore(&head, &tail, value, newNode);
break;
case 5:
deleteAtFirst(&head, &tail);
break;
case 6:
deleteAtLast(&head, &tail);
break;
case 7:
printf("Enter node value after which to delete: ");
scanf("%d", &value);
deleteAfter(&head, &tail, value);
break;
case 8:
printf("Enter node value before which to delete: ");
scanf("%d", &value);
deleteBefore(&head, &tail, value);
break;
case 9:
printf("Enter value to search: ");
scanf("%d", &value);
searchNode(head, value);
break;
case 10:
reverseList(&head, &tail);
printf("List reversed\n");
break;
case 11:
displayForward(head);
break;
case 12:
displayBackward(tail);
break;
case 13:
exit(0);
default:
printf("Invalid choice!\n");
}
}
return 0;
}