// Week 8 Thursday Lecture // Modified as a debugging exercise // for Week 10 Revision // Using search and delete approach 2 #include #include struct node { int data; struct node *next; }; struct node *create_node(int data, struct node *next); void print_list(struct node *head); struct node *insert_at_tail(struct node *head, int data); //Deletion related functions struct node *delete_first(struct node *head); void delete_all(struct node *head); struct node *search_and_delete(struct node *head, int value); struct node *search_and_delete_all(struct node *head, int value); int main(void) { //create a node with data value i using function //add node to tail/end of list struct node *head = NULL; printf("Search and delete empty list\n"); head = search_and_delete(head, 0); print_list(head); for (int i = 0; i < 10; i++) { head = insert_at_tail(head, i); } print_list(head); printf("Search and delete middle: 5 \n"); head = search_and_delete(head, 5); print_list(head); printf("Search and delete value not found: 99\n"); head = search_and_delete(head, 99); print_list(head); printf("Search and head: 0\n"); head = search_and_delete(head, 0); print_list(head); printf("Search and tail: 9\n"); head = search_and_delete(head, 9); print_list(head); delete_all(head); // check for memory leaks return 0; } // Approach 2. struct node *search_and_delete(struct node *head, int value) { if (head == NULL) { return head; } // Approach 2: Just use 1 pointer to traverse // but check the next node struct node *current = head; if (current->data == value) { head = head->next; free(current); return head; } while (current->next != NULL && current->next->data != value) { current = current->next; } struct node *temporary = current->next; if (temporary != NULL) { current->next = temporary->next; free(temporary); } return head; } struct node *create_node(int data, struct node *next) { struct node *new_node = malloc(sizeof(struct node)); if (new_node == NULL) { return NULL; } new_node->data = data; new_node->next = next; return new_node; } void print_list(struct node *head) { printf("list:\n"); struct node *curr = head; while (curr != NULL) { printf("%d ", curr->data); curr = curr->next; } printf("\n"); } struct node *insert_at_tail(struct node *head, int data) { struct node *new_node = create_node(data, NULL); struct node *current = head; // Case for when the list is empty if (head == NULL) { head = new_node; } else { // Find the last node in the list while (current->next != NULL) { current = current->next; } current->next = new_node; } return head; } // Deletes and frees the memory of the first node in the list // returns the head of the list struct node *delete_first(struct node *head) { if (head == NULL) { return NULL; } struct node *tmp = head; head = head->next; free(tmp); return head; } // frees memory of all nodes in the given list void delete_all(struct node *head) { struct node *current = head; while (current != NULL) { head = head->next; free(current); current = head; } } // searches for a value in the list, deletes it and frees // the memory. // returns the head of the list // Only deletes the first occurrence of a value in the list struct node *search_and_delete1(struct node *head, int value) { struct node *previous = NULL; struct node *current = head; while (current != NULL && current->data != value) { previous = current; current = current->next; } // If current is NULL // We did not find the element // (this includes the case where the list is empty) // so we have nothing to delete. if (current != NULL) { // If previous is NULL we are deleting first element if (previous == NULL) { head = head->next; } else { previous->next = current->next; } free(current); } return head; } struct node *search_and_delete_all(struct node *head, int value) { struct node *previous = NULL; struct node *current = head; while (current != NULL) { if (current->data == value) { if (previous == NULL) { head = head->next; free(current); current = head; } else { previous->next = current->next; free(current); current = previous->next; } } else { previous = current; current = current->next; } } return head; }