It works, but it seems a bit long winded. I'd like some critiquing.
#include <stdio.h>
#include <stdlib.h>
struct node
{
int data;
struct node * previous;
struct node * next;
};
struct linked_list
{
struct node * first;
struct node * last;
};
struct linked_list * init_list(struct node * node)
{
struct linked_list * ret = malloc(sizeof(struct linked_list));
ret->first = node;
ret->last = node;
return ret;
}
struct node * create_node(int data)
{
struct node * ret = malloc(sizeof(struct node));
ret->data = data;
ret->previous = NULL;
ret->next = NULL;
return ret;
}
void destroy_list(struct linked_list * list)
{
struct node * node = list->first, *next = NULL;
while(node != NULL)
{
next = node->next;
free(node);
node = next;
}
free(list);
}
void push_front(struct linked_list * list, struct node * node)
{
if(list->first != NULL)
{
node->next = list->first;
list->first->previous = node;
}
else list->last = node;
list->first = node;
}
void push_back(struct linked_list * list, struct node * node)
{
if(list->last != NULL)
{
node->previous = list->last;
list->last->next = node;
list->last = node;
}
else push_front(list, node);
}
void insert_after(struct node * node, struct node * to_add)
{
to_add->previous = node;
to_add->next = node->next;
node->next = to_add;
}
void remove_node(struct node * node)
{
node->previous->next = node->next;
node->next->previous = node->previous;
free(node);
}
if(...) { ...; ...; } else ...;
where theelse
is not a block isn't a particularly clear style to read. If theif
has a block, theelse
should have a block too. The one inpush_front
is especially sneaky because theelse
has a statement immediately following it. \$\endgroup\$