Skip to content

Instantly share code, notes, and snippets.

@z-------------
Last active November 16, 2019 09:23
Show Gist options
  • Save z-------------/2808b06d37beb6db33d1e3e148f1aa0e to your computer and use it in GitHub Desktop.
Save z-------------/2808b06d37beb6db33d1e3e148f1aa0e to your computer and use it in GitHub Desktop.
#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;
}
}
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));
#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