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;
}
相关推荐
SuperByteMaster8 小时前
keil 工程 .gitignore配置文件
c语言
汉克老师9 小时前
GESP2025年3月认证C++五级( 第三部分编程题(1、平均分配))
c++·算法·贪心算法·排序·gesp5级·gesp五级
老花眼猫12 小时前
编制椭圆旋转绘图函数
c语言·经验分享·青少年编程·课程设计
智者知已应修善业12 小时前
【51单片机2个按键控制流水灯运行与暂停】2023-9-6
c++·经验分享·笔记·算法·51单片机
云泽80814 小时前
C++11 核心特性全解:列表初始化、右值引用与移动语义实战
开发语言·c++
AI进化营-智能译站14 小时前
ROS2 C++开发系列12-用多态与虚函数构建可扩展的ROS2机器人行为模块
开发语言·c++·ai·机器人
iCxhust15 小时前
微机原理实践教程(C语言篇)---A002流水灯
c语言·开发语言·单片机·嵌入式硬件·51单片机·课程设计·微机原理
Morwit15 小时前
QML组件之间的通信方案(暴露子组件)
c++·qt·职场和发展
qeen8715 小时前
【数据结构】建堆的时间复杂度讨论与TOP-K问题
c语言·数据结构·c++·学习·
图码15 小时前
如何用多种方法判断字符串是否为回文?
开发语言·数据结构·c++·算法·阿里云·线性回归·数字雕刻