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;
}
相关推荐
tan180°3 分钟前
Boost搜索引擎 网络库与前端(4)
linux·网络·c++·搜索引擎
bkspiderx34 分钟前
C++经典的数据结构与算法之经典算法思想:贪心算法(Greedy)
数据结构·c++·算法·贪心算法
郝学胜-神的一滴1 小时前
避免使用非const全局变量:C++中的最佳实践 (C++ Core Guidelines)
开发语言·c++·程序人生
l1t2 小时前
轻量级XML读写库Mini-XML的编译和使用
xml·c语言·解析器
晚云与城3 小时前
今日分享:C++ Stack和queue(栈与队列)
开发语言·c++
小莞尔3 小时前
【51单片机】【protues仿真】基于51单片机停车场的车位管理系统
c语言·开发语言·单片机·嵌入式硬件·51单片机
bikong74 小时前
一种高效绘制余晖波形的方法Qt/C++
数据库·c++·qt
xianyinsuifeng4 小时前
Oracle 10g → Oracle 19c 升级后问题解决方案(Pro*C 项目)
c语言·数据库·oracle
深耕AI4 小时前
【MFC文档与视图结构:数据“仓库”与“橱窗”的梦幻联动 + 初始化“黑箱”大揭秘!】
c++·mfc
学c语言的枫子4 小时前
数据结构——双向链表
c语言·数据结构·链表