typedef struct node { void* data; struct node* prev; struct node* next; } node_t; typedef struct list { struct node* first; struct node* last; long length; } list_t; // Create and free list list_t* list_new(); void list_free(list_t *l); // Create and free nodes node_t* node_new(void* data); // WARNING: free does free the node data by default // to prevent freeing of the data set data to 0 before removing from the list void node_free(node_t* n); // List operations void list_insert(list_t *l, node_t* n); void list_append(list_t *l, node_t* n); void list_remove(list_t *l, node_t *n); void list_clear(list_t *l); // Default implementation of specal list modes // Queue void list_queue_push(list_t *l, void* data); void* list_queue_pop(list_t *l); // Stack void list_stack_push(list_t *l, void* data); void* list_stack_pop(list_t *l); #include "linkedlist.h" #include list_t* list_new() { list_t *l = malloc(sizeof(list_t)); l->first = 0; l->last = 0; l->length = 0; return l; } node_t* node_new(void* data) { node_t *n = malloc(sizeof(node_t)); n->prev = 0; n->next = 0; n->data = data; return n; } void node_free(node_t* n) { free(n->data); free(n); } void list_insert(list_t *l, node_t* n) { if (l->first != 0) { n->next = l->first; l->first->prev = n; l->first = n; } else { // assuming list is empty l->first = n; l->last = n; } l->length += 1; } void list_append(list_t *l, node_t* n) { if (l->last != 0) { n->prev = l->last; l->last->next = n; l->last = n; } else { // assuming list is empty l->first = n; l->last = n; } l->length += 1; } void list_remove(list_t *l, node_t *n) { if (n->prev != 0 && n->next != 0) { // We are dealing with a middle node n->prev->next = n->next; n->next->prev = n->prev; } else if (n->prev != 0 && n->next == 0) { // We are dealing with a last node n->prev->next = 0; l->last = n->prev; } else if (n->prev == 0 && n->next != 0) { // We are dealing with a first node n->next->prev = 0; l->first = n->next; } else if (n->prev == 0 && n->next == 0) { // We are dealing with a single node l->first = 0; l->last = 0; } l->length -= 1; } void list_clear(list_t *l) { while(l->first != 0) { list_remove(l, l->first); } } void list_free(list_t *l) { if (l->length > 0) { list_clear(l); } free(l); } // Queue (FIFO) void list_queue_push(list_t *l, void* data) { list_append(l, node_new(data)); } void* list_queue_pop(list_t *l) { void* data = 0; if (l->first != 0) { data = l->first->data; l->first->data = 0; list_remove(l, l->first); } return data; } // Stack (FILO) void list_stack_push(list_t *l, void* data) { list_append(l, node_new(data)); } void* list_stack_pop(list_t *l) { void* data = 0; if (l->last != 0) { data = l->last->data; l->last->data = 0; list_remove(l, l->last); } return data; } #include #include #include "linkedlist.h" void list_test1() { printf("start\n"); list_t *l; l = list_new(); printf("list count: %ld\n", l->length); list_append(l, node_new("Hello 1")); list_append(l, node_new("Hello 2")); list_append(l, node_new("Hello 3")); list_append(l, node_new("Hello 4")); list_append(l, node_new("Hello 5")); printf("list count: %ld\n", l->length); list_insert(l, node_new("Hello 1")); list_insert(l, node_new("Hello 2")); list_insert(l, node_new("Hello 3")); list_insert(l, node_new("Hello 4")); list_insert(l, node_new("Hello 5")); printf("list count: %ld\n", l->length); node_t *n = l->first; while(n != 0) { printf("item: %s\n", (char*) n->data); n = n->next; } list_remove(l, l->last); printf("list count: %ld\n", l->length); list_clear(l); printf("list count: %ld\n", l->length); list_free(l); printf("end\n"); } void list_test2() { printf("start\n"); list_t *l; l = list_new(); list_queue_push(l, "Hello 1"); list_queue_push(l, "Hello 2"); list_queue_push(l, "Hello 3"); list_queue_push(l, "Hello 4"); list_queue_push(l, "Hello 5"); printf("list count: %ld\n", l->length); char *data = 0; data = (char*)list_queue_pop(l); //printf("list count: %ld\n", l->length); while(data != 0) { printf("item: %s\n", data); data = (char*)list_queue_pop(l); //printf("list count: %ld\n", l->length); } printf("list count: %ld\n", l->length); list_clear(l); printf("\n"); list_stack_push(l, "Hello 1"); list_stack_push(l, "Hello 2"); list_stack_push(l, "Hello 3"); list_stack_push(l, "Hello 4"); list_stack_push(l, "Hello 5"); printf("list count: %ld\n", l->length); data = (char*)list_stack_pop(l); //printf("list count: %ld\n", l->length); while(data != 0) { printf("item: %s\n", data); data = (char*)list_stack_pop(l); //printf("list count: %ld\n", l->length); } printf("list count: %ld\n", l->length); list_free(l); printf("end\n"); } void list_test3() { list_t *l = list_new(); int i = 0; for(i=0; i<1000000; i++) { int *d = malloc(sizeof(int)); *d = i; list_stack_push(l, d); } int *data = (int*)list_stack_pop(l); while(data != 0) { printf("%i\n", *data); data = (int*)list_stack_pop(l); } list_free(l); } int main(int argc, char *argv[]) { list_test1(); list_test2(); //list_test3(); return 0; }
23300cookie-checkA Linked List in C