C99 linkedlist 容器实现

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;
}
相关推荐
A懿轩A29 分钟前
C/C++ 数据结构与算法【数组】 数组详细解析【日常学习,考研必备】带图+详细代码
c语言·数据结构·c++·学习·考研·算法·数组
机器视觉知识推荐、就业指导34 分钟前
C++设计模式:享元模式 (附文字处理系统中的字符对象案例)
c++
半盏茶香34 分钟前
在21世纪的我用C语言探寻世界本质 ——编译和链接(编译环境和运行环境)
c语言·开发语言·c++·算法
Ronin3052 小时前
11.vector的介绍及模拟实现
开发语言·c++
✿ ༺ ོIT技术༻2 小时前
C++11:新特性&右值引用&移动语义
linux·数据结构·c++
字节高级特工2 小时前
【C++】深入剖析默认成员函数3:拷贝构造函数
c语言·c++
计算机学长大白3 小时前
C中设计不允许继承的类的实现方法是什么?
c语言·开发语言
唐诺8 小时前
几种广泛使用的 C++ 编译器
c++·编译器
XH华8 小时前
初识C语言之二维数组(下)
c语言·算法
冷眼看人间恩怨9 小时前
【Qt笔记】QDockWidget控件详解
c++·笔记·qt·qdockwidget