/* * Simple implementation of unsorted linked list of integers. * Uses a "sentinel" (dummy) node to simplify coding somewhat. */ #include #include #include "int-list.h" /* Helper functions (declarations). */ int_list_node_t * int_list_make_node(int data, int_list_node_t * n); void int_list_free_r(int_list_node_t * n); int int_list_remove_r(int_list_node_t * n, int elem); void int_list_print_r(FILE * outstream, const char * fmt, int_list_node_t * n); /* * Create empty list. * Returns NULL on error. */ int_list_t * int_list_create(void) { int_list_t * temp = malloc(sizeof(int_list_t)); if (temp != NULL) { temp->head = int_list_make_node(0, NULL); if (temp->head == NULL) return NULL; } return temp; } /* * Free list (and all its elements). */ void int_list_free(int_list_t * t) { int_list_free_r(t->head); free(t); } /* * Insert element into list. * Returns -1 on error. */ int int_list_insert(int_list_t * l, int elem) { int_list_node_t * n = int_list_make_node(elem, l->head->next); if (n == NULL) { return -1; } else { l->head->next = n; return 0; } } /* * Remove selected element everywhere it occurs. * Returns -1 if element is not found. */ int int_list_remove(int_list_t * l, int elem) { return int_list_remove_r(l->head, elem); } /* * Print all elements of list, one per line. Parameter "fmt" is * a format string suitable for passing to fprintf. */ void int_list_print(FILE * outstream, const char * fmt, int_list_t * l) { int_list_print_r(outstream, fmt, l->head->next); } /* * Helper functions. */ /* Make a list node. */ int_list_node_t * int_list_make_node(int data, int_list_node_t * next) { int_list_node_t * n = malloc(sizeof(int_list_node_t)); if (n != NULL) { n->data = data; n->next = next; } return n; } /* Free node at n and all its successors. */ void int_list_free_r(int_list_node_t * n) { if (n != NULL) { int_list_free_r(n->next); free(n); } } /* * Remove element "elem" from list starting at n->next. ("n" must not * be NULL). * Returns how many elements were removed. */ int int_list_remove_r(int_list_node_t * n, int elem) { if (n->next == NULL) { return 0; } else { if (n->next->data == elem) { int_list_node_t * temp = n->next; n->next = temp->next; free(temp); return 1 + int_list_remove_r(n, elem); } else { return int_list_remove_r(n->next, elem); } } } /* Print n and all its successors, using "fmt" as a format string for * fprintf. */ void int_list_print_r(FILE * outstream, const char * fmt, int_list_node_t * n) { if (n != NULL) { fprintf(outstream, fmt, n->data); int_list_print_r(outstream, fmt, n->next); } }