diff --git a/linked-list.c b/linked-list.c index 006e7c4..6a6d8d7 100644 --- a/linked-list.c +++ b/linked-list.c @@ -3,17 +3,27 @@ #include #include "assert.h" + struct list_node { int data; struct list_node *next; }; typedef struct list_node list_node_t; -int list_length(list_node_t * list) { +struct list { + list_node_t * head; +}; +typedef struct list list_t; + +void list_init (list_t * list) { + list->head = NULL; +} + +int list_length(list_t * list) { list_node_t *cur; int count = 0; - cur = list; + cur = list->head; while (cur != NULL) { count++; cur = cur->next; @@ -22,14 +32,14 @@ int list_length(list_node_t * list) { return count; } -bool list_empty(list_node_t * list) { - return (list == NULL); +bool list_empty(list_t * list) { + return (list->head == NULL); } -void list_print(list_node_t * list) { +void list_print(list_t * list) { list_node_t *cur; - cur = list; + cur = list->head; while (cur != NULL) { printf("%d ", cur->data); cur = cur->next; @@ -37,22 +47,29 @@ void list_print(list_node_t * list) { printf("\n"); } -void list_add(list_node_t * list, list_node_t * item) { +void list_add(list_t * list, list_node_t * item) { list_node_t *cur; - cur = list; - assert(cur != NULL); - while (cur->next != NULL) { - cur = cur->next; + if (list_empty(list)) { + list->head = item; + } else { + cur = list->head; + while (cur->next != NULL) { + cur = cur->next; + } + cur->next = item; } - - cur->next = item; } -void list_remove(list_node_t * list, list_node_t * item) { +void list_remove(list_t * list, list_node_t * item) { list_node_t *cur; - cur = list; + if (list->head->data == item->data) { + list->head = list->head->next; + return; + } + + cur = list->head; assert(cur != NULL); while (cur->next != NULL) { @@ -64,28 +81,34 @@ void list_remove(list_node_t * list, list_node_t * item) { } } +/* FIXME + * list_node_t list_revert(list_node_t *list) { +} */ + int main(int argc, char *argv[]) { - list_node_t *emptylist = NULL; + list_t *emptylist = malloc(sizeof(list_t)); + list_init(emptylist); assert(list_length(emptylist) == 0); assert(list_empty(emptylist) == true); list_print(emptylist); printf("list_length = %d\n", list_length(emptylist)); + list_t *foolist = malloc(sizeof(list_t)); list_node_t foo = { 1, NULL }; + list_add(foolist, &foo); - assert(list_length(&foo) == 1); - assert(list_empty(&foo) == false); - list_print(&foo); - printf("list_length = %d\n", list_length(&foo)); + assert(list_length(foolist) == 1); + assert(list_empty(foolist) == false); + list_print(foolist); + printf("list_length = %d\n", list_length(foolist)); // append something to foo list_node_t bar = { 2, NULL }; - list_add(&foo, &bar); + list_add(foolist, &bar); - assert(list_length(&foo) == 2); - assert(list_length(&bar) == 1); - list_print(&foo); - printf("list_length = %d\n", list_length(&foo)); + assert(list_length(foolist) == 2); + list_print(foolist); + printf("list_length = %d\n", list_length(foolist)); // append more const int howmany = 100; @@ -93,31 +116,54 @@ int main(int argc, char *argv[]) { list_node_t *newnode = malloc(sizeof(list_node_t)); newnode->data = i; - list_add(&foo, newnode); + list_add(foolist, newnode); } - assert(list_length(&foo) == 2 + howmany); - list_print(&foo); - printf("list_length = %d\n", list_length(&foo)); + assert(list_length(foolist) == 2 + howmany); + list_print(foolist); + printf("list_length = %d\n", list_length(foolist)); // remove something list_node_t toremove = { 23, NULL }; - list_remove(&foo, &toremove); - assert(list_length(&foo) == 2 + howmany - 1); - list_print(&foo); - printf("list_length = %d\n", list_length(&foo)); + list_remove(foolist, &toremove); + assert(list_length(foolist) == 2 + howmany - 1); + list_print(foolist); + printf("list_length = %d\n", list_length(foolist)); + + // remove last item + toremove.data = howmany - 1; + list_remove(foolist, &toremove); + assert(list_length(foolist) == 2 + howmany - 2); + list_print(foolist); + printf("list_length = %d\n", list_length(foolist)); // remove something - toremove.data = 99; - list_remove(&foo, &toremove); - assert(list_length(&foo) == 2 + howmany - 2); - list_print(&foo); - printf("list_length = %d\n", list_length(&foo)); + toremove.data = 1; + list_remove(foolist, &toremove); + assert(list_length(foolist) == 2 + howmany - 3); + list_print(foolist); + printf("list_length = %d\n", list_length(foolist)); // remove something toremove.data = 1; - list_remove(&foo, &toremove); - /* FIXME can't delete first 1 */ - assert(list_length(&foo) == 2 + howmany - 3); - list_print(&foo); - printf("list_length = %d\n", list_length(&foo)); + list_remove(foolist, &toremove); + assert(list_length(foolist) == 2 + howmany - 4); + list_print(foolist); + printf("list_length = %d\n", list_length(foolist)); + + /* remove everything */ + for (int i = 0; i < howmany; i++) { + toremove.data = i; + list_remove(foolist, &toremove); + } + assert(list_length(foolist) == 1); + list_print(foolist); + printf("list_length = %d\n", list_length(foolist)); + + /* remove last remaining item */ + toremove.data = 2; + list_remove(foolist, &toremove); + assert(list_length(foolist) == 0); + assert(list_empty(foolist) == true); + list_print(foolist); + printf("list_length = %d\n", list_length(foolist)); }