linkedlist.h
cpp
#ifndef LINKEDLIST_H
#define LINKEDLIST_H
#ifdef __cplusplus
extern "C" {
#endif
struct linkedlist_node
{
struct linkedlist* linkedlist;
struct linkedlist_node* prev;
struct linkedlist_node* next;
};
struct linkedlist
{
int count;
struct linkedlist_node* last;
struct linkedlist_node* first;
void(*clear)(struct linkedlist* my);
int(*add_first)(struct linkedlist* my, struct linkedlist_node* node);
int(*add_last)(struct linkedlist* my, struct linkedlist_node* node);
int(*add_after)(struct linkedlist* my, struct linkedlist_node* position, struct linkedlist_node* node);
int(*add_before)(struct linkedlist* my, struct linkedlist_node* position, struct linkedlist_node* node);
int(*remove_first)(struct linkedlist* my);
int(*remove_last)(struct linkedlist* my);
int(*remove)(struct linkedlist* my, struct linkedlist_node* node);
struct linkedlist_node* (*find)(struct linkedlist* my, int(*predicate)(struct linkedlist_node*));
struct linkedlist_node* (*rfind)(struct linkedlist* my, int(*predicate)(struct linkedlist_node*));
};
int linkedlist_new(struct linkedlist* list);
int linkedlist_node_new(struct linkedlist_node* node);
#ifdef __cplusplus
}
#endif
#endif
linkedlist.c
cpp
#include "linkedlist.h"
#include <memory.h>
static void
linkedlist_clear(struct linkedlist* my)
{
my->count = 0;
my->last = NULL;
my->first = NULL;
}
static int
linkedlist_add_first(struct linkedlist* my, struct linkedlist_node* node)
{
struct linkedlist_node* current;
if (NULL == node)
{
return 0;
}
node->linkedlist = NULL;
node->next = NULL;
node->prev = NULL;
if (NULL == my->last)
{
my->last = node;
my->first = node;
my->count = 0;
}
else
{
current = my->first;
node->next = current;
current->prev = node;
my->first = node;
}
my->count++;
node->linkedlist = my;
return 1;
}
static int
linkedlist_add_last(struct linkedlist* my, struct linkedlist_node* node)
{
if (NULL == node)
{
return 0;
}
node->linkedlist = NULL;
node->next = NULL;
node->prev = NULL;
if (NULL == my->last)
{
my->first = node;
my->last = node;
my->count = 0;
my->count++;
node->linkedlist = my;
return 1;
}
else
{
return my->add_after(my, my->last, node);
}
}
static int
linkedlist_add_after(struct linkedlist* my, struct linkedlist_node* position, struct linkedlist_node* node)
{
struct linkedlist_node* current;
if (NULL == position)
{
return 0;
}
if (NULL == node)
{
return 0;
}
node->linkedlist = NULL;
node->next = NULL;
node->prev = NULL;
current = position->next;
position->next = node;
if (NULL != current)
{
current->prev = node;
}
node->prev = position;
node->next = current;
if (position == my->last)
{
my->last = node;
}
my->count++;
node->linkedlist = my;
return 1;
}
static int
linkedlist_add_before(struct linkedlist* my, struct linkedlist_node* position, struct linkedlist_node* node)
{
struct linkedlist_node* current;
if (NULL == position)
{
return 0;
}
if (NULL == node)
{
return 0;
}
node->linkedlist = NULL;
node->next = NULL;
node->prev = NULL;
current = position->prev;
if (NULL == current)
{
return my->add_first(my, node);
}
current->next = node;
position->prev = node;
node->next = position;
node->prev = current;
if (position == my->first)
{
my->first = node;
}
my->count++;
node->linkedlist = my;
return 1;
}
static int
linkedlist_remove_first(struct linkedlist* my)
{
struct linkedlist_node* first;
struct linkedlist_node* current;
first = my->first;
if (NULL == first)
{
return 0;
}
current = first->next;
first->prev = NULL;
first->linkedlist = NULL;
first->next = NULL;
if (NULL != current)
{
current->prev = NULL;
}
my->count--;
if (my->count <= 0)
{
my->count = 0;
my->first = NULL;
my->last = NULL;
current = NULL;
}
my->first = current;
return 1;
}
static int
linkedlist_remove_last(struct linkedlist* my)
{
struct linkedlist_node* last;
struct linkedlist_node* current;
last = my->last;
if (NULL == last)
{
return 0;
}
current = last->prev;
last->prev = NULL;
last->linkedlist = NULL;
last->next = NULL;
if (NULL != current)
{
current->next = NULL;
}
my->count--;
if (my->count <= 0)
{
my->count = 0;
my->first = NULL;
my->last = NULL;
current = NULL;
}
my->last = current;
return 1;
}
static int
linkedlist_remove(struct linkedlist* my, struct linkedlist_node* node)
{
struct linkedlist_node* previous;
struct linkedlist_node* next;
if (NULL == node)
{
return 0;
}
if (node == my->first)
{
return my->remove_first(my);
}
if (node == my->last)
{
return my->remove_last(my);
}
previous = node->prev;
next = node->next;
previous->next = next;
next->prev = previous;
my->count--;
if (my->count <= 0)
{
my->count = 0;
my->first = NULL;
my->last = NULL;
}
node->next = NULL;
node->prev = NULL;
node->linkedlist = NULL;
return 1;
}
static struct linkedlist_node*
linkedlist_find(struct linkedlist* my, int(*predicate)(struct linkedlist_node*))
{
struct linkedlist_node* node;
if (my->count < 1)
{
return NULL;
}
node = my->first;
while (NULL != node)
{
if (predicate(node))
{
return node;
}
node = node->next;
}
return NULL;
}
static struct linkedlist_node*
linkedlist_rfind(struct linkedlist* my, int(*predicate)(struct linkedlist_node*))
{
struct linkedlist_node* node;
if (my->count < 1)
{
return NULL;
}
node = my->last;
while (NULL != node)
{
if (predicate(node))
{
return node;
}
node = node->prev;
}
return NULL;
}
int
linkedlist_new(struct linkedlist* list)
{
if (NULL != list)
{
list->add_first = linkedlist_add_first;
list->add_last = linkedlist_add_last;
list->clear = linkedlist_clear;
list->remove = linkedlist_remove;
list->remove_first = linkedlist_remove_first;
list->remove_last = linkedlist_remove_last;
list->add_after = linkedlist_add_after;
list->add_before = linkedlist_add_before;
list->find = linkedlist_find;
list->rfind = linkedlist_rfind;
linkedlist_clear(list);
return 1;
}
return 0;
}
int
linkedlist_node_new(struct linkedlist_node* node)
{
if (NULL != node)
{
node->next = NULL;
node->prev = NULL;
node->linkedlist = NULL;
return 1;
}
return 0;
}