Header file:
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
typedef struct linked_list linked_list;
typedef struct cons cons;
void append(cons *cons, int value);
void linked_list_append(linked_list *ll, int value);
int size(linked_list *ll);
void insert_after(cons *c, int value, int index, int current);
void linked_list_insert_after(linked_list *ll, int value, int index);
void delete(cons *c, int index, int current);
void linked_list_delete(linked_list *ll, int index);
linked_list *new_linked_list(void);
void linked_list_destroy(linked_list *ll);
void destroy(cons *c);
int get(cons *c, int index, int current);
int linked_list_get(linked_list *ll, int index);
void cons_print(cons *c);
void linked_list_print(linked_list *ll);
Actual code:
#include "ll.h"
struct cons {
int value;
cons *next;
};
struct linked_list {
int size;
cons *list;
};
linked_list *new_linked_list(void) {
linked_list *ll = malloc(sizeof(linked_list));
assert(ll);
ll->size = 0;
ll->list = NULL;
return ll;
}
int linked_list_get(linked_list *ll, int index) {
assert(ll);
assert(index >= 0);
assert(index <= (ll->size - 1));
return get(ll->list, index, 0);
}
int get(cons *c, int index, int current) {
if (index == current) {
return c->value;
} else {
return get(c->next, index, ++current);
}
}
void linked_list_append(linked_list *ll, int value) {
assert(ll);
(ll->size)++;
if (ll->list) {
append(ll->list, value);
} else {
cons *new = malloc(sizeof(cons));
new->value = value;
new->next = NULL;
ll->list = new;
}
}
void append(cons *c, int value) {
if (c->next) {
append(c->next, value);
} else {
cons *new = malloc(sizeof(cons));
new->value = value;
new->next = NULL;
c->next = new;
}
}
void linked_list_insert_after(linked_list *ll, int value, int index) {
assert(ll);
assert(index >= 0);
assert(index <= (ll->size - 1));
ll->size++;
insert_after(ll->list, value, index, 0);
}
void insert_after(cons *c, int value, int index, int current) {
if (index == current) {
cons *new = malloc(sizeof(cons));
new->value = value;
new->next = c->next;
c->next = new;
} else {
insert_after(c->next, value, index, ++current);
}
}
int linked_list_size(linked_list *ll) {
if (ll) {
return ll->size;
} else {
return -1;
}
}
void linked_list_delete(linked_list *ll, int index) {
assert(ll);
assert(index >= 0);
assert(index <= (ll->size - 1));
ll->size--;
delete(ll->list, index, 0);
}
void delete(cons *c, int index, int current) {
if (index == current) {
cons *temp = c;
*c = *(c->next);
free(temp);
} else {
delete(c->next, index, ++current);
}
}
void linked_list_destroy(linked_list *ll) {
if (ll) {
destroy(ll->list);
free(ll);
}
}
void destroy(cons *c) {
if (c) {
destroy(c->next);
free(c);
}
}
void linked_list_print(linked_list *ll) {
assert(ll);
cons_print(ll->list);
}
void cons_print(cons *c) {
if (c) {
printf("%d ", c->value);
cons_print(c->next);
} else {
printf("\n");
}
}
int main(void) {
linked_list *new = new_linked_list();
linked_list_print(new);
linked_list_append(new, 2);
linked_list_print(new); // 2
linked_list_append(new, 3);
linked_list_print(new); // 2 3
linked_list_append(new, 4);
linked_list_print(new); // 2 3 4
linked_list_insert_after(new, 15, 1);
linked_list_print(new); // 2 3 15 4
linked_list_delete(new, 1);
linked_list_print(new); // 2 15 4
printf("get 0: %d\n", linked_list_get(new, 0));
printf("get 2: %d\n", linked_list_get(new, 2));
printf("get 1: %d\n", linked_list_get(new, 1));
linked_list_destroy(new);
return 0;
}
I'm trying to split up my code into a code file and a header file, but it doesn't feel right. I'm not actually hiding any of the implementation details from the client if they can see the helper methods. What's the correct way to do this?
My
delete
function works, but I don't really understand it. Previously the meat of it wasif (index == current) { cons *temp = c; c = temp->next; free(temp); }
but this didn't work. Why?
I've tried to incorporate style / memory advice I've gotten in my previous submissions stack and binary search tree. I don't think there are any memory leaks, but I'd like some double checking.
Any and all criticism is welcome here.