int dlist_remove(DList *list, DListElmt *element, void **data) { if (dlist_size(list) == 0 || element == NULL) return -1; /* * Store data for DListElmt to be removed */ *data = element->data; /* * Remove element. There are four cases: * * 1. One element in list * 2. Head of list * 3. Tail of list * 4. Middle of list */ if (dlist_size(list) == 1) { /* Case 1: One element is list */ list->head = NULL; list->tail = NULL; } else if (dlist_is_head(list, element)) { /* Case 2: Element is head */ list->head = element->next; list->head->prev = NULL; } else if (dlist_is_tail(list, element)) { /* Case 3: Element is tail */ list->tail = element->prev; list->tail->next = NULL; } else { /* Case 4: Element is in middle */ element->prev->next = element->next; element->next->prev = element->prev; } /* * Free memory */ free(element); /* * Update list stats */ list->size--; return 0; }
int dlist_ins_prev(DList *list, DListElmt *element, const void *data) { DListElmt *new_element; /* * Only allow element to be NULL if the list is empty */ if (element == NULL && dlist_size(list) != 0) return -1; /* * Allocate storage for element and set payload */ if ((new_element = (DListElmt *)malloc(sizeof(DListElmt))) == NULL) return -1; new_element->data = (void *) data; /* * Insert element into list */ if (dlist_size(list) == 0) { /* Case 1: List is empty */ new_element->next = NULL; new_element->prev = NULL; list->head = new_element; list->tail = new_element; } else { /* Case 2: List is not empty */ /* Hook up new_element */ new_element->prev = element->prev; new_element->next = element; /* Hook up element */ element->prev = new_element; /* Hook up next element and update head if necessary*/ if (dlist_is_head(list, element)) list->head = new_element; else new_element->prev->next = new_element; } return 0; }
int main(int argc, char **argv) { DList list; DListElmt *element; int *data, i; /***************************************************************************** * * * Initialize the doubly-linked list. * * * *****************************************************************************/ dlist_init(&list, free); /***************************************************************************** * * * Perform some doubly-linked list operations. * * * *****************************************************************************/ element = dlist_head(&list); for (i = 10; i > 0; i--) { if ((data = (int *)malloc(sizeof(int))) == NULL) return 1; *data = i; if (dlist_ins_prev(&list, dlist_head(&list), data) != 0) return 1; } print_list(&list); element = dlist_head(&list); for (i = 0; i < 8; i++) element = dlist_next(element); data = dlist_data(element); fprintf(stdout, "Removing an element after the one containing %03d\n", *data); if (dlist_remove(&list, element, (void **)&data) != 0) return 1; print_list(&list); fprintf(stdout, "Inserting 011 at the tail of the list\n"); *data = 11; if (dlist_ins_next(&list, dlist_tail(&list), data) != 0) return 1; print_list(&list); fprintf(stdout, "Removing an element at the tail of the list\n"); element = dlist_tail(&list); if (dlist_remove(&list, element, (void **)&data) != 0) return 1; print_list(&list); fprintf(stdout, "Inserting 012 just before the tail of the list\n"); *data = 12; if (dlist_ins_prev(&list, dlist_tail(&list), data) != 0) return 1; print_list(&list); fprintf(stdout, "Iterating and removing the fourth element\n"); element = dlist_head(&list); element = dlist_next(element); element = dlist_prev(element); element = dlist_next(element); element = dlist_prev(element); element = dlist_next(element); element = dlist_next(element); element = dlist_next(element); if (dlist_remove(&list, element, (void **)&data) != 0) return 1; print_list(&list); fprintf(stdout, "Inserting 013 before the first element\n"); *data = 13; if (dlist_ins_prev(&list, dlist_head(&list), data) != 0) return 1; print_list(&list); fprintf(stdout, "Removing an element at the head of the list\n"); if (dlist_remove(&list, dlist_head(&list), (void **)&data) != 0) return 1; print_list(&list); fprintf(stdout, "Inserting 014 just after the head of the list\n"); *data = 14; if (dlist_ins_next(&list, dlist_head(&list), data) != 0) return 1; print_list(&list); fprintf(stdout, "Inserting 015 two elements after the head of the list\n"); if ((data = (int *)malloc(sizeof(int))) == NULL) return 1; *data = 15; element = dlist_head(&list); element = dlist_next(element); if (dlist_ins_next(&list, element, data) != 0) return 1; print_list(&list); i = dlist_is_head(dlist_head(&list)); fprintf(stdout, "Testing dlist_is_head...Value=%d (1=OK)\n", i); i = dlist_is_head(dlist_tail(&list)); fprintf(stdout, "Testing dlist_is_head...Value=%d (0=OK)\n", i); i = dlist_is_tail(dlist_tail(&list)); fprintf(stdout, "Testing dlist_is_tail...Value=%d (1=OK)\n", i); i = dlist_is_tail(dlist_head(&list)); fprintf(stdout, "Testing dlist_is_tail...Value=%d (0=OK)\n", i); /***************************************************************************** * * * Destroy the doubly-linked list. * * * *****************************************************************************/ fprintf(stdout, "Destroying the list\n"); dlist_destroy(&list); return 0; }