/* * Ex. No. 6: IMPLEMENTATION OF DOUBLY LINKED LIST * Library Borrowed Book Record System using a doubly linked list * Supports: INSERT (beginning/end/position), DELETE (beginning/end/position/by ID), * SEARCH by Book ID, DISPLAY (forward/reverse) */ #include #include #include #define TITLE_LEN 60 #define AUTHOR_LEN 50 struct Node { int bookId; char title[TITLE_LEN]; char author[AUTHOR_LEN]; struct Node *prev; struct Node *next; }; struct Node *head = NULL; /* Count nodes in list */ int countNodes(void) { int count = 0; struct Node *cur = head; while (cur != NULL) { count++; cur = cur->next; } return count; } /* Return the last node, or NULL if the list is empty */ struct Node *lastNode(void) { struct Node *cur = head; if (cur == NULL) { return NULL; } while (cur->next != NULL) { cur = cur->next; } return cur; } struct Node *makeNode(int bookId, const char *title, const char *author) { struct Node *node = (struct Node *)malloc(sizeof(struct Node)); if (node == NULL) { printf("Memory allocation failed.\n"); exit(1); } node->bookId = bookId; strcpy(node->title, title); strcpy(node->author, author); node->prev = NULL; node->next = NULL; return node; } /* i) Insert at beginning */ void insertBeginning(int bookId, const char *title, const char *author) { struct Node *node = makeNode(bookId, title, author); node->next = head; if (head != NULL) { head->prev = node; } head = node; printf("Record inserted at beginning.\n"); } /* ii) Insert at end */ void insertEnd(int bookId, const char *title, const char *author) { struct Node *node = makeNode(bookId, title, author); struct Node *last = lastNode(); if (last == NULL) { head = node; } else { last->next = node; node->prev = last; } printf("Record inserted at end.\n"); } /* iii) Insert at a given position (1-based) */ void insertAtPosition(int pos, int bookId, const char *title, const char *author) { int size = countNodes(); if (pos < 1 || pos > size + 1) { printf("Invalid position. Valid range is 1 to %d.\n", size + 1); return; } if (pos == 1) { insertBeginning(bookId, title, author); return; } struct Node *prev = head; int i; for (i = 1; i < pos - 1; i++) { prev = prev->next; } struct Node *node = makeNode(bookId, title, author); node->next = prev->next; node->prev = prev; if (prev->next != NULL) { prev->next->prev = node; } prev->next = node; printf("Record inserted at position %d.\n", pos); } /* iv) Delete from beginning */ void deleteBeginning(void) { if (head == NULL) { printf("List is empty. Nothing to delete.\n"); return; } struct Node *doomed = head; head = head->next; if (head != NULL) { head->prev = NULL; } printf("Deleted record: BookID=%d, Title=%s\n", doomed->bookId, doomed->title); free(doomed); } /* v) Delete from end */ void deleteEnd(void) { if (head == NULL) { printf("List is empty. Nothing to delete.\n"); return; } struct Node *doomed = lastNode(); if (doomed->prev == NULL) { head = NULL; } else { doomed->prev->next = NULL; } printf("Deleted record: BookID=%d, Title=%s\n", doomed->bookId, doomed->title); free(doomed); } /* vi) Delete from a given position (1-based) */ void deleteAtPosition(int pos) { int size = countNodes(); if (head == NULL) { printf("List is empty. Nothing to delete.\n"); return; } if (pos < 1 || pos > size) { printf("Invalid position. Valid range is 1 to %d.\n", size); return; } if (pos == 1) { deleteBeginning(); return; } struct Node *doomed = head; int i; for (i = 1; i < pos; i++) { doomed = doomed->next; } doomed->prev->next = doomed->next; if (doomed->next != NULL) { doomed->next->prev = doomed->prev; } printf("Deleted record: BookID=%d, Title=%s\n", doomed->bookId, doomed->title); free(doomed); } /* vii) Delete a record by its Book ID */ void deleteById(int bookId) { struct Node *cur = head; while (cur != NULL && cur->bookId != bookId) { cur = cur->next; } if (cur == NULL) { printf("Book ID %d not found.\n", bookId); return; } if (cur->prev == NULL) { head = cur->next; } else { cur->prev->next = cur->next; } if (cur->next != NULL) { cur->next->prev = cur->prev; } printf("Deleted record: BookID=%d, Title=%s\n", cur->bookId, cur->title); free(cur); } /* viii) Search by Book ID */ void search(int bookId) { struct Node *cur = head; int pos = 1; while (cur != NULL) { if (cur->bookId == bookId) { printf("Found at position %d: BookID=%d, Title=%s, Author=%s\n", pos, cur->bookId, cur->title, cur->author); return; } cur = cur->next; pos++; } printf("Book ID %d not found.\n", bookId); } /* ix) Display all records in forward order */ void displayForward(void) { if (head == NULL) { printf("List is empty.\n"); return; } struct Node *cur = head; int pos = 1; printf("--- Borrowed Book Records (Forward) ---\n"); while (cur != NULL) { printf("%d) BookID=%d, Title=%s, Author=%s\n", pos, cur->bookId, cur->title, cur->author); cur = cur->next; pos++; } } /* x) Display all records in reverse order */ void displayReverse(void) { if (head == NULL) { printf("List is empty.\n"); return; } struct Node *cur = lastNode(); int pos = countNodes(); printf("--- Borrowed Book Records (Reverse) ---\n"); while (cur != NULL) { printf("%d) BookID=%d, Title=%s, Author=%s\n", pos, cur->bookId, cur->title, cur->author); cur = cur->prev; pos--; } } /* Free all remaining nodes before exit */ void freeList(void) { struct Node *cur = head; while (cur != NULL) { struct Node *next = cur->next; free(cur); cur = next; } head = NULL; } void readBook(int *bookId, char *title, char *author) { printf("Enter book ID: "); scanf("%d", bookId); printf("Enter book title: "); scanf(" %59[^\n]", title); printf("Enter author name: "); scanf(" %49[^\n]", author); } int main(void) { int choice, bookId, pos; char title[TITLE_LEN]; char author[AUTHOR_LEN]; do { printf("\n===== Library Borrowed Book Record System =====\n"); printf("1. Insert at Beginning\n"); printf("2. Insert at End\n"); printf("3. Insert at a Given Position\n"); printf("4. Delete from Beginning\n"); printf("5. Delete from End\n"); printf("6. Delete from a Given Position\n"); printf("7. Delete by Book ID\n"); printf("8. Search by Book ID\n"); printf("9. Display Forward\n"); printf("10. Display Reverse\n"); printf("11. Exit\n"); printf("Enter your choice: "); scanf("%d", &choice); switch (choice) { case 1: readBook(&bookId, title, author); insertBeginning(bookId, title, author); break; case 2: readBook(&bookId, title, author); insertEnd(bookId, title, author); break; case 3: printf("Enter position: "); scanf("%d", &pos); readBook(&bookId, title, author); insertAtPosition(pos, bookId, title, author); break; case 4: deleteBeginning(); break; case 5: deleteEnd(); break; case 6: printf("Enter position: "); scanf("%d", &pos); deleteAtPosition(pos); break; case 7: printf("Enter book ID to delete: "); scanf("%d", &bookId); deleteById(bookId); break; case 8: printf("Enter book ID to search: "); scanf("%d", &bookId); search(bookId); break; case 9: displayForward(); break; case 10: displayReverse(); break; case 11: printf("Exiting...\n"); break; default: printf("Invalid choice.\n"); } } while (choice != 11); freeList(); return 0; }