Refactor Doubly Linked List implementation

This commit is contained in:
2026-01-22 17:39:57 +05:30
committed by GitHub
parent d7eeba8a48
commit 66fafe8813
+136 -125
View File
@@ -1,136 +1,147 @@
#include <stdio.h>
#include <stdlib.h>
typedef struct element {
int key;
} element;
typedef struct node *nodeptr;
// Define the DLL Node
struct Node {
int data;
struct Node *prev; // Pointer to previous node
struct Node *next; // Pointer to next node
};
typedef struct node {
nodeptr llink;
element item;
nodeptr rlink;
} node;
// Global Head Pointer
struct Node *head = NULL;
void insert(nodeptr head, int data);
void delete(nodeptr head, nodeptr deleted);
void display(nodeptr head);
nodeptr search(nodeptr head, int key);
// a) Insert a node (Create/Append) - 15 Marks
// We insert at the END to simulate "Creating" a list naturally
void insert(int value) {
struct Node *temp;
// 1. Allocate memory
struct Node *newNode = (struct Node *)malloc(sizeof(struct Node));
if (newNode == NULL) {
printf("Memory allocation failed\n");
return;
}
// 2. Set data
newNode->data = value;
newNode->next = NULL; // Since it will be the last node
// 3. Case 1: List is Empty
if (head == NULL) {
newNode->prev = NULL; // First node has no prev
head = newNode;
printf("Node %d inserted as head.\n", value);
return;
}
// 4. Case 2: List has data. Traverse to the end.
temp = head;
while (temp->next != NULL) {
temp = temp->next;
}
// 5. Link the new node
temp->next = newNode; // Old last node points to new node
newNode->prev = temp; // New node points back to old last node
printf("Node %d inserted at end.\n", value);
}
// b) Delete a node (by value) - 15 Marks
void delete(int value) {
struct Node *temp = head;
// 1. Check if list is empty
if (head == NULL) {
printf("List is empty.\n");
return;
}
// 2. Search for the node
while (temp != NULL && temp->data != value) {
temp = temp->next;
}
// 3. If node not found
if (temp == NULL) {
printf("Element %d not found.\n", value);
return;
}
// --- Deletion Logic ---
// Case A: Deleting the Head Node
if (temp == head) {
head = head->next; // Move head forward
if (head != NULL) {
head->prev = NULL; // New head's prev must be NULL
}
}
// Case B: Deleting a Middle or Last Node
else {
// Link the previous node to the next node
temp->prev->next = temp->next;
// If there IS a next node (i.e., we are not deleting the last node),
// Link the next node back to the previous node
if (temp->next != NULL) {
temp->next->prev = temp->prev;
}
}
// 4. Free memory
free(temp);
printf("Node %d deleted.\n", value);
}
// c) Display the list - 5 Marks
void display() {
struct Node *temp = head;
if (head == NULL) {
printf("List is empty.\n");
return;
}
printf("List (Forward): NULL <-> ");
while (temp != NULL) {
printf("%d <-> ", temp->data);
temp = temp->next;
}
printf("NULL\n");
}
int main() {
int choice, data;
nodeptr node_to_delete;
int choice, val;
printf("--- Doubly Linked List Program ---\n");
nodeptr head = (nodeptr)malloc(sizeof(node));
if (head == NULL) {
fprintf(stderr, "Memory allocation failed for head node.\n");
exit(1);
while (1) {
printf("\n1. Insert (Create)\n2. Delete\n3. Display\n4. Exit\n");
printf("Enter choice: ");
scanf("%d", &choice);
switch (choice) {
case 1:
printf("Enter value: ");
scanf("%d", &val);
insert(val);
break;
case 2:
printf("Enter value to delete: ");
scanf("%d", &val);
delete(val);
break;
case 3:
display();
break;
case 4:
return 0;
default:
printf("Invalid Choice\n");
}
head->llink = head;
head->rlink = head;
while (1) {
printf("\n--- Doubly Linked List Menu ---\n");
printf("1. Insert (at front)\n");
printf("2. Delete (by key)\n");
printf("3. Display List\n");
printf("4. Exit\n");
printf("Enter your choice: ");
scanf("%d", &choice);
switch (choice) {
case 1:
printf("Enter number to insert: ");
scanf("%d", &data);
insert(head, data);
printf("Item %d inserted.\n", data);
break;
case 2:
printf("Enter number to delete: ");
scanf("%d", &data);
node_to_delete = search(head, data);
if (node_to_delete == NULL) {
printf("Item %d not found in the list.\n", data);
} else {
delete(head, node_to_delete);
printf("Item %d deleted.\n", data);
}
break;
case 3:
display(head);
break;
case 4:
printf("Exiting program.\n");
free(head);
exit(0);
default:
printf("Invalid choice. Please try again.\n");
}
}
return 0;
}
return 0;
}
void insert(nodeptr head, int data) {
nodeptr newnode = (nodeptr)malloc(sizeof(node));
if (newnode == NULL) {
fprintf(stderr, "Memory allocation failed for new node!\n");
exit(1);
}
newnode->item.key = data;
newnode->llink = head;
newnode->rlink = head->rlink;
head->rlink->llink = newnode;
head->rlink = newnode;
}
void delete(nodeptr head, nodeptr deleted) {
if (head == deleted) {
printf("Deletion of the head node not permitted!\n");
} else {
deleted->llink->rlink = deleted->rlink;
deleted->rlink->llink = deleted->llink;
free(deleted);
}
}
nodeptr search(nodeptr head, int key) {
nodeptr temp = head->rlink;
while (temp != head) {
if (temp->item.key == key) {
return temp;
}
temp = temp->rlink;
}
return NULL;
}
void display(nodeptr head) {
nodeptr temp = head->rlink;
if (temp == head) {
printf("List is empty.\n");
return;
}
printf("List: ");
while (temp != head) {
printf("%d ", temp->item.key);
temp = temp->rlink;
}
printf("\n");
}