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;
}
相关推荐
低头专研1 小时前
Markdown标题序号处理工具——用 C 语言实现
c语言·开发语言·typora·markdown文件标题编号·md文件标题序号
刚入门的大一新生3 小时前
C++初阶-C++入门基础
开发语言·c++
weixin_428498494 小时前
Visual Studio 中使用 Clang 作为 C/C++ 编译器时,设置优化选项方法
c语言·c++·visual studio
菜鸡中的奋斗鸡→挣扎鸡4 小时前
第十四届蓝桥杯大赛软件赛省赛C/C++ 大学 B 组
c语言·c++·蓝桥杯
南玖yy4 小时前
探索 C 语言数据结构:从基础到实践
c语言·开发语言·数据结构
前进的程序员5 小时前
Linux C 与 C 语言的区别及开发差异
linux·运维·c语言
流星白龙5 小时前
【C++算法】50.分治_归并_翻转对
c++·算法
q567315235 小时前
使用libcurl编写爬虫程序指南
开发语言·c++·爬虫
しかし1181146 小时前
C语言队列的实现
c语言·开发语言·数据结构·数据库·经验分享·链表
矛取矛求6 小时前
C++ STL 详解 ——list 的深度解析与实践指南
c++·list