Last active 1 week ago

Revision 4c01f812086a64a67e0eedf6739da2bcfcf25d74

6.c Raw
1/*
2 * Ex. No. 6: IMPLEMENTATION OF DOUBLY LINKED LIST
3 * Library Borrowed Book Record System using a doubly linked list
4 * Supports: INSERT (beginning/end/position), DELETE (beginning/end/position/by ID),
5 * SEARCH by Book ID, DISPLAY (forward/reverse)
6 */
7#include <stdio.h>
8#include <stdlib.h>
9#include <string.h>
10
11#define TITLE_LEN 60
12#define AUTHOR_LEN 50
13
14struct Node {
15 int bookId;
16 char title[TITLE_LEN];
17 char author[AUTHOR_LEN];
18 struct Node *prev;
19 struct Node *next;
20};
21
22struct Node *head = NULL;
23
24/* Count nodes in list */
25int countNodes(void) {
26 int count = 0;
27 struct Node *cur = head;
28 while (cur != NULL) {
29 count++;
30 cur = cur->next;
31 }
32 return count;
33}
34
35/* Return the last node, or NULL if the list is empty */
36struct Node *lastNode(void) {
37 struct Node *cur = head;
38 if (cur == NULL) {
39 return NULL;
40 }
41 while (cur->next != NULL) {
42 cur = cur->next;
43 }
44 return cur;
45}
46
47struct Node *makeNode(int bookId, const char *title, const char *author) {
48 struct Node *node = (struct Node *)malloc(sizeof(struct Node));
49 if (node == NULL) {
50 printf("Memory allocation failed.\n");
51 exit(1);
52 }
53 node->bookId = bookId;
54 strcpy(node->title, title);
55 strcpy(node->author, author);
56 node->prev = NULL;
57 node->next = NULL;
58 return node;
59}
60
61/* i) Insert at beginning */
62void insertBeginning(int bookId, const char *title, const char *author) {
63 struct Node *node = makeNode(bookId, title, author);
64 node->next = head;
65 if (head != NULL) {
66 head->prev = node;
67 }
68 head = node;
69 printf("Record inserted at beginning.\n");
70}
71
72/* ii) Insert at end */
73void insertEnd(int bookId, const char *title, const char *author) {
74 struct Node *node = makeNode(bookId, title, author);
75 struct Node *last = lastNode();
76 if (last == NULL) {
77 head = node;
78 } else {
79 last->next = node;
80 node->prev = last;
81 }
82 printf("Record inserted at end.\n");
83}
84
85/* iii) Insert at a given position (1-based) */
86void insertAtPosition(int pos, int bookId, const char *title, const char *author) {
87 int size = countNodes();
88 if (pos < 1 || pos > size + 1) {
89 printf("Invalid position. Valid range is 1 to %d.\n", size + 1);
90 return;
91 }
92 if (pos == 1) {
93 insertBeginning(bookId, title, author);
94 return;
95 }
96
97 struct Node *prev = head;
98 int i;
99 for (i = 1; i < pos - 1; i++) {
100 prev = prev->next;
101 }
102
103 struct Node *node = makeNode(bookId, title, author);
104 node->next = prev->next;
105 node->prev = prev;
106 if (prev->next != NULL) {
107 prev->next->prev = node;
108 }
109 prev->next = node;
110 printf("Record inserted at position %d.\n", pos);
111}
112
113/* iv) Delete from beginning */
114void deleteBeginning(void) {
115 if (head == NULL) {
116 printf("List is empty. Nothing to delete.\n");
117 return;
118 }
119 struct Node *doomed = head;
120 head = head->next;
121 if (head != NULL) {
122 head->prev = NULL;
123 }
124 printf("Deleted record: BookID=%d, Title=%s\n", doomed->bookId, doomed->title);
125 free(doomed);
126}
127
128/* v) Delete from end */
129void deleteEnd(void) {
130 if (head == NULL) {
131 printf("List is empty. Nothing to delete.\n");
132 return;
133 }
134 struct Node *doomed = lastNode();
135 if (doomed->prev == NULL) {
136 head = NULL;
137 } else {
138 doomed->prev->next = NULL;
139 }
140 printf("Deleted record: BookID=%d, Title=%s\n", doomed->bookId, doomed->title);
141 free(doomed);
142}
143
144/* vi) Delete from a given position (1-based) */
145void deleteAtPosition(int pos) {
146 int size = countNodes();
147 if (head == NULL) {
148 printf("List is empty. Nothing to delete.\n");
149 return;
150 }
151 if (pos < 1 || pos > size) {
152 printf("Invalid position. Valid range is 1 to %d.\n", size);
153 return;
154 }
155 if (pos == 1) {
156 deleteBeginning();
157 return;
158 }
159
160 struct Node *doomed = head;
161 int i;
162 for (i = 1; i < pos; i++) {
163 doomed = doomed->next;
164 }
165
166 doomed->prev->next = doomed->next;
167 if (doomed->next != NULL) {
168 doomed->next->prev = doomed->prev;
169 }
170 printf("Deleted record: BookID=%d, Title=%s\n", doomed->bookId, doomed->title);
171 free(doomed);
172}
173
174/* vii) Delete a record by its Book ID */
175void deleteById(int bookId) {
176 struct Node *cur = head;
177 while (cur != NULL && cur->bookId != bookId) {
178 cur = cur->next;
179 }
180 if (cur == NULL) {
181 printf("Book ID %d not found.\n", bookId);
182 return;
183 }
184
185 if (cur->prev == NULL) {
186 head = cur->next;
187 } else {
188 cur->prev->next = cur->next;
189 }
190 if (cur->next != NULL) {
191 cur->next->prev = cur->prev;
192 }
193 printf("Deleted record: BookID=%d, Title=%s\n", cur->bookId, cur->title);
194 free(cur);
195}
196
197/* viii) Search by Book ID */
198void search(int bookId) {
199 struct Node *cur = head;
200 int pos = 1;
201 while (cur != NULL) {
202 if (cur->bookId == bookId) {
203 printf("Found at position %d: BookID=%d, Title=%s, Author=%s\n",
204 pos, cur->bookId, cur->title, cur->author);
205 return;
206 }
207 cur = cur->next;
208 pos++;
209 }
210 printf("Book ID %d not found.\n", bookId);
211}
212
213/* ix) Display all records in forward order */
214void displayForward(void) {
215 if (head == NULL) {
216 printf("List is empty.\n");
217 return;
218 }
219 struct Node *cur = head;
220 int pos = 1;
221 printf("--- Borrowed Book Records (Forward) ---\n");
222 while (cur != NULL) {
223 printf("%d) BookID=%d, Title=%s, Author=%s\n", pos, cur->bookId, cur->title, cur->author);
224 cur = cur->next;
225 pos++;
226 }
227}
228
229/* x) Display all records in reverse order */
230void displayReverse(void) {
231 if (head == NULL) {
232 printf("List is empty.\n");
233 return;
234 }
235 struct Node *cur = lastNode();
236 int pos = countNodes();
237 printf("--- Borrowed Book Records (Reverse) ---\n");
238 while (cur != NULL) {
239 printf("%d) BookID=%d, Title=%s, Author=%s\n", pos, cur->bookId, cur->title, cur->author);
240 cur = cur->prev;
241 pos--;
242 }
243}
244
245/* Free all remaining nodes before exit */
246void freeList(void) {
247 struct Node *cur = head;
248 while (cur != NULL) {
249 struct Node *next = cur->next;
250 free(cur);
251 cur = next;
252 }
253 head = NULL;
254}
255
256void readBook(int *bookId, char *title, char *author) {
257 printf("Enter book ID: ");
258 scanf("%d", bookId);
259 printf("Enter book title: ");
260 scanf(" %59[^\n]", title);
261 printf("Enter author name: ");
262 scanf(" %49[^\n]", author);
263}
264
265int main(void) {
266 int choice, bookId, pos;
267 char title[TITLE_LEN];
268 char author[AUTHOR_LEN];
269
270 do {
271 printf("\n===== Library Borrowed Book Record System =====\n");
272 printf("1. Insert at Beginning\n");
273 printf("2. Insert at End\n");
274 printf("3. Insert at a Given Position\n");
275 printf("4. Delete from Beginning\n");
276 printf("5. Delete from End\n");
277 printf("6. Delete from a Given Position\n");
278 printf("7. Delete by Book ID\n");
279 printf("8. Search by Book ID\n");
280 printf("9. Display Forward\n");
281 printf("10. Display Reverse\n");
282 printf("11. Exit\n");
283 printf("Enter your choice: ");
284 scanf("%d", &choice);
285
286 switch (choice) {
287 case 1:
288 readBook(&bookId, title, author);
289 insertBeginning(bookId, title, author);
290 break;
291 case 2:
292 readBook(&bookId, title, author);
293 insertEnd(bookId, title, author);
294 break;
295 case 3:
296 printf("Enter position: ");
297 scanf("%d", &pos);
298 readBook(&bookId, title, author);
299 insertAtPosition(pos, bookId, title, author);
300 break;
301 case 4:
302 deleteBeginning();
303 break;
304 case 5:
305 deleteEnd();
306 break;
307 case 6:
308 printf("Enter position: ");
309 scanf("%d", &pos);
310 deleteAtPosition(pos);
311 break;
312 case 7:
313 printf("Enter book ID to delete: ");
314 scanf("%d", &bookId);
315 deleteById(bookId);
316 break;
317 case 8:
318 printf("Enter book ID to search: ");
319 scanf("%d", &bookId);
320 search(bookId);
321 break;
322 case 9:
323 displayForward();
324 break;
325 case 10:
326 displayReverse();
327 break;
328 case 11:
329 printf("Exiting...\n");
330 break;
331 default:
332 printf("Invalid choice.\n");
333 }
334 } while (choice != 11);
335
336 freeList();
337 return 0;
338}
339