mirror of
https://github.com/Manoj-HV30/ds-lab-codes.git
synced 2026-05-16 19:35:22 +00:00
Refactor Doubly Linked List implementation
This commit is contained in:
+136
-125
@@ -1,136 +1,147 @@
|
|||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.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 {
|
// Global Head Pointer
|
||||||
nodeptr llink;
|
struct Node *head = NULL;
|
||||||
element item;
|
|
||||||
nodeptr rlink;
|
|
||||||
} node;
|
|
||||||
|
|
||||||
void insert(nodeptr head, int data);
|
// a) Insert a node (Create/Append) - 15 Marks
|
||||||
void delete(nodeptr head, nodeptr deleted);
|
// We insert at the END to simulate "Creating" a list naturally
|
||||||
void display(nodeptr head);
|
void insert(int value) {
|
||||||
nodeptr search(nodeptr head, int key);
|
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 main() {
|
||||||
int choice, data;
|
int choice, val;
|
||||||
nodeptr node_to_delete;
|
printf("--- Doubly Linked List Program ---\n");
|
||||||
|
|
||||||
nodeptr head = (nodeptr)malloc(sizeof(node));
|
while (1) {
|
||||||
if (head == NULL) {
|
printf("\n1. Insert (Create)\n2. Delete\n3. Display\n4. Exit\n");
|
||||||
fprintf(stderr, "Memory allocation failed for head node.\n");
|
printf("Enter choice: ");
|
||||||
exit(1);
|
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;
|
return 0;
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
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");
|
|
||||||
}
|
|
||||||
|
|||||||
Reference in New Issue
Block a user