This repository has been archived on 2021-10-31. You can view files and clone it, but cannot push or open issues or pull requests.
sys_prog/list.c

126 lines
2.7 KiB
C
Raw Normal View History

2019-08-11 16:32:58 +00:00
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define TYPE int
//A list is one of:
// - (make-note element next)
// - '() -> NULL
struct node {
TYPE element;
struct node* prev;
struct node* next;
};
typedef struct node node_t;
typedef struct {
node* first;
} list_t;
size_t list_length(const list_t* self) {
size_t length = 0;
node_t* i = self->first;
while (i != NULL) {
length++;
i = self->next;
}
return length;
}
node_t* list_ith(const list_t* self, const size_t position) {
size_t found;
node_t* elem = list_ith_or_last(self, position, &found);
return found != position ? NULL : elem;
}
node_t* list_ith_or_last(const list_t* self, const size_t position,
const size_t* returned) {
node_t* to_reach = self->first;
size_t i;
for (i = 0; i < position && to_reach->next != NULL; i++) {
to_reach = to_reach->next;
}
*returned = i;
return to_reach;
}
node_t* make_node(TYPE element) {
node_t* node = malloc(sizeof(node));
node->element = element;
node->next = NULL;
node->prev = NULL;
}
void free_list(const list_t* list) {
while(list->first != NULL) {
free(list_remove(self, 0));
}
}
size_t list_copy_slice(const list_t* self, const list_t* destination,
const size_t from, const size_t to) {
if (from >= to) {
return 0;
}
free_list(destination);
size_t start, i;
node_t* to_copy = list_ith_or_last(self, to, &start);
if (to_copy == NULL) {
return 0;
}
for(i = start; i > from; i--) {
node_t* copied = malloc(sizeof(node_t));
memcpy(copied, src, sizeof(node_t));
list_insert(destination, 0, copied);
}
return start - from;
}
int list_insert(const list_t* self, const size_t position, const node_t* node) {
if (self->first == NULL) {
return 1;
}
if (position == 0) {
node->next = self->first;
node->prev = NULL;
self->first = node;
return 0;
}
node_t* to_reach = list_ith(self, position - 1);
if (to_reach == NULL) {
return 2;
}
to_reach->next->prev = node;
node->next = to_reach->next;
node->prev = to_reach;
to_reach->next = node;
return 0;
}
node_t* list_remove(const list_t* self, const size_t position) {
if(position == 0) {
node_t* to_remove = self->first;
self->first = to_remove->next;
return to_remove;
}
node_t* to_reach = list_ith(self, position - 1);
if (to_reach == NULL || to_reach->next == NULL) {
return NULL;
}
node_t* to_remove = to_reach->next;
to_reach->next = to_reach->next->next;
to_reach->next->prev = to_reach;
return to_remove;
}