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;
}
相关推荐
悠仁さん8 小时前
【C++】AVL 树
c++
wuminyu8 小时前
JVM规范学习总结:解释器与JIT编译器如何处理JVM字节码
java·linux·c语言·jvm·c++
小徐不徐说9 小时前
序列化与反序列化:把 C++ 对象可靠地保存下来
开发语言·数据库·c++·php
ragnwang9 小时前
Notes: Python pybind11 import C++ module
开发语言·c++·python
充值内卷10 小时前
我给桌面加了个鱼缸:C++ 写后端,WebView2 里养一座 Three.js 小岛
开发语言·javascript·c++
樱花树下的数学喵13 小时前
手写简易 STL string|C++ 字符串底层实现
开发语言·c++
AI吃大瓜13 小时前
指针压力表读数3:C/C++实现指针压力表读数(可实时检测)
c++·指针读数·指针压力表·压力表自动读数·压力表读数
-银雾鸢尾-13 小时前
两数之和-C++实现
c++·算法
j7~14 小时前
【动态规划算法专题】动态规划五部曲实战:泰波那契数、三步问题、最小花费爬楼梯
c++·算法·动态规划·数据结构与算法
jimy114 小时前
C++ 报错的 qualifiers 的意思
开发语言·c++