-
-
Save z-------------/2808b06d37beb6db33d1e3e148f1aa0e to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #include <stdlib.h> | |
| #include "ll.h" | |
| struct ll* ll_create() { | |
| struct ll* list = (struct ll*) malloc(sizeof(struct ll)); | |
| list->head = NULL; | |
| list->length = 0; | |
| return list; | |
| } | |
| struct ll_node* ll_node_create(void* data) { | |
| struct ll_node* node = (struct ll_node*) malloc(sizeof(struct ll_node)); | |
| node->data = data; | |
| node->next = NULL; | |
| return node; | |
| } | |
| void ll_node_free(struct ll_node* node) { | |
| if (node->next != NULL) | |
| ll_node_free(node->next); | |
| free(node->data); | |
| free(node); | |
| } | |
| void ll_node_sfree(struct ll_node* node) { | |
| if (node->next != NULL) | |
| ll_node_sfree(node->next); | |
| free(node); | |
| } | |
| void ll_free(struct ll* list) { | |
| if (list->head != NULL) | |
| ll_node_free(list->head); | |
| free(list); | |
| } | |
| void ll_sfree(struct ll* list) { | |
| if (list->head != NULL) | |
| ll_node_sfree(list->head); | |
| free(list); | |
| } | |
| int ll_isempty(struct ll* list) { | |
| return list->length == 0; | |
| } | |
| int ll_length(struct ll* list) { | |
| return list->length; | |
| } | |
| int ll_indexof(struct ll* list, void* data) { | |
| int i = 0; | |
| struct ll_node* cur = list->head; | |
| while (cur != NULL) { | |
| if (cur->data == data) break; | |
| cur = cur->next; | |
| ++i; | |
| } | |
| return i; | |
| } | |
| struct ll_node* ll_getlast_node(struct ll* list) { | |
| if (ll_isempty(list)) return NULL; | |
| struct ll_node* cur = list->head; | |
| while (cur->next != NULL) { | |
| cur = cur->next; | |
| } | |
| return cur; | |
| } | |
| struct ll_node* ll_get_node(struct ll* list, int i) { | |
| if (i < 0) return NULL; | |
| int cur_i = 0; | |
| struct ll_node* cur = list->head; | |
| while (cur_i < i && cur != NULL) { | |
| cur = cur->next; | |
| ++cur_i; | |
| } | |
| return cur; | |
| } | |
| void* ll_getlast(struct ll* list) { | |
| struct ll_node* last = ll_getlast_node(list); | |
| if (last == NULL) return NULL; | |
| return last->data; | |
| } | |
| void* ll_get(struct ll* list, int i) { | |
| struct ll_node* node = ll_get_node(list, i); | |
| if (node == NULL) return NULL; | |
| return node->data; | |
| } | |
| void ll_set(struct ll* list, int i, void* data) { | |
| struct ll_node* node = ll_get_node(list, i); | |
| if (node == NULL) return; | |
| free(node->data); | |
| node->data = data; | |
| } | |
| void ll_append(struct ll* list, void* data) { | |
| struct ll_node* new = ll_node_create(data); | |
| struct ll_node* last = ll_getlast_node(list); | |
| if (last == NULL) { // empty list | |
| list->head = new; | |
| } else { | |
| last->next = new; | |
| } | |
| ++(list->length); | |
| } | |
| void ll_insert(struct ll* list, int i, void* data) { | |
| struct ll_node* new = ll_node_create(data); | |
| if (i == 0) { | |
| struct ll_node* oldhead = list->head; | |
| list->head = new; | |
| new->next = oldhead; | |
| } else { | |
| struct ll_node* bef = ll_get_node(list, i - 1); | |
| struct ll_node* aft = bef->next; | |
| bef->next = new; | |
| new->next = aft; | |
| } | |
| ++(list->length); | |
| } | |
| void ll_insert_list(struct ll* alist, int i, struct ll* blist) { | |
| if (ll_isempty(blist)) return; | |
| struct ll_node* aft; | |
| if (i == 0) { | |
| aft = alist->head; | |
| alist->head = blist->head; | |
| } else { | |
| struct ll_node* bef = ll_get_node(alist, i - 1); | |
| aft = bef->next; | |
| bef->next = blist->head; | |
| } | |
| ll_getlast_node(blist)->next = aft; | |
| alist->length += blist->length; | |
| free(blist); | |
| } | |
| void ll_concat(struct ll* alist, struct ll* blist) { | |
| if (ll_isempty(alist)) | |
| alist->head = blist->head; | |
| else | |
| ll_getlast_node(alist)->next = blist->head; | |
| alist->length += blist->length; | |
| free(blist); | |
| } | |
| void ll_each(struct ll* list, void (*f)(void* data)) { | |
| struct ll_node* cur = list->head; | |
| while (cur != NULL) { | |
| f(cur->data); | |
| cur = cur->next; | |
| } | |
| } | |
| void ll_eachi(struct ll* list, void (*f)(void* data, int index, int length)) { | |
| struct ll_node* cur = list->head; | |
| const int l = list->length; | |
| int i = 0; | |
| while (cur != NULL) { | |
| f(cur->data, i++, l); | |
| cur = cur->next; | |
| } | |
| } | |
| void ll_reduce(struct ll* list, void* c, void (*f)(void* c, void* data)) { | |
| struct ll_node* cur = list->head; | |
| while (cur != NULL) { | |
| f(c, cur->data); | |
| cur = cur->next; | |
| } | |
| } | |
| void ll_swap(struct ll* list, int a_i, int b_i) { | |
| struct ll_node* a = ll_get_node(list, a_i); | |
| if (a == NULL) return; | |
| struct ll_node* b = ll_get_node(list, b_i); | |
| if (b == NULL) return; | |
| void* a_data = a->data; | |
| a->data = b->data; | |
| b->data = a_data; | |
| } | |
| void ll_sort(struct ll* list, int (*compare)(void* a, void* b)) { | |
| const int len = list->length; | |
| int i = 1; | |
| while (i < len) { | |
| int j = i; | |
| while (j > 0 && compare(ll_get(list, j - 1), ll_get(list, j)) > 0) { | |
| ll_swap(list, j, j - 1); | |
| --j; | |
| } | |
| ++i; | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| struct ll_node { | |
| void* data; | |
| struct ll_node* next; | |
| }; | |
| struct ll { | |
| struct ll_node* head; | |
| int length; | |
| }; | |
| struct ll* ll_create(); | |
| struct ll_node* ll_node_create(void* data); | |
| void ll_node_free(struct ll_node*); | |
| void ll_node_sfree(struct ll_node*); | |
| void ll_free(struct ll*); | |
| void ll_sfree(struct ll*); | |
| int ll_isempty(struct ll*); | |
| int ll_length(struct ll*); | |
| int ll_indexof(struct ll*, void* data); | |
| struct ll_node* ll_getlast_node(struct ll*); | |
| struct ll_node* ll_get_node(struct ll*, int index); | |
| void* ll_getlast(struct ll*); | |
| void* ll_get(struct ll*, int index); | |
| void ll_set(struct ll*, int index, void* data); | |
| void ll_append(struct ll*, void* data); | |
| void ll_insert(struct ll*, int index, void* data); | |
| void ll_insert_list(struct ll*, int index, struct ll*); | |
| void ll_concat(struct ll*, struct ll*); | |
| void ll_each(struct ll*, void (*)(void* data)); | |
| void ll_eachi(struct ll*, void (*)(void* data, int index, int length)); | |
| void ll_reduce(struct ll*, void* c, void (*)(void* c, void* data)); | |
| void ll_swap(struct ll*, int, int); | |
| void ll_sort(struct ll*, int (*)(void* a, void* b)); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #include <stdio.h> | |
| #include "ll.h" | |
| void print_list_item(void* data, int i, int l) { | |
| printf("[%d] %d%s", i, *((int*) data), i == l - 1 ? "\n" : ", "); | |
| } | |
| void print_list(struct ll* list) { | |
| ll_eachi(list, &print_list_item); | |
| } | |
| void square(void* data) { | |
| const int n = *((int*) data); | |
| *((int*) data) = n * n; | |
| } | |
| void sum_f(void* c, void* data) { | |
| *((int*) c) += *((int*) data); | |
| } | |
| int compare(void* a, void* b) { | |
| return *((int*) a) - *((int*) b); | |
| } | |
| int main() { | |
| int sum; | |
| struct ll* list = ll_create(); | |
| int a = 5, b = 101, c = 8, d = 3, e = 69; | |
| ll_append(list, &a); | |
| ll_append(list, &b); | |
| ll_append(list, &c); | |
| ll_insert(list, 0, &d); | |
| ll_insert(list, 2, &e); | |
| printf("List A: "); | |
| print_list(list); | |
| sum = 0; | |
| ll_reduce(list, &sum, &sum_f); | |
| printf("Sum = %d\n", sum); | |
| struct ll* list_two = ll_create(); | |
| int f = 42, g = 420; | |
| ll_append(list_two, &f); | |
| ll_append(list_two, &g); | |
| printf("List B: "); | |
| print_list(list_two); | |
| sum = 0; | |
| ll_reduce(list_two, &sum, &sum_f); | |
| printf("Sum = %d\n", sum); | |
| ll_concat(list, list_two); | |
| printf("Combined list: "); | |
| print_list(list); | |
| sum = 0; | |
| ll_reduce(list, &sum, &sum_f); | |
| printf("Sum = %d\n", sum); | |
| ll_each(list, &square); | |
| printf("List after square: "); | |
| print_list(list); | |
| sum = 0; | |
| ll_reduce(list, &sum, &sum_f); | |
| printf("Sum = %d\n", sum); | |
| printf("Mean = %f\n", (double) sum / ll_length(list)); | |
| struct ll* list_three = ll_create(); | |
| int h = -314, k = -6969; | |
| ll_append(list_three, &h); | |
| ll_append(list_three, &k); | |
| printf("List C: "); | |
| print_list(list_three); | |
| ll_insert_list(list, 2, list_three); | |
| printf("List A after insertion: "); | |
| print_list(list); | |
| ll_sort(list, &compare); | |
| printf("List A after sorting: "); | |
| print_list(list); | |
| ll_sfree(list); | |
| return 0; | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment