仿照redis源码的Adlist双端链表实现一个自己的双端链表(1)

文档均在代码中注释,解释请看代码

#ifndef FERI_LIST_H
#define FERI_LIST_H
/*普通结点*/
typedef struct feri_listnode {
    struct feri_listnode *pre;
    struct feri_listnode *nex;
    void *value;
} feri_listnode;
/*迭代器*/
typedef struct feri_iter {
    feri_listnode *next;
    int direction;
} feri_iter;
/*哑结点,本篇博文仅仅使用到了前三项,至于后面的三个函数指针的功能将在下一篇博文中详细解释*/
typedef struct feri_list {
    feri_listnode *head;
    feri_listnode *tail;
    unsigned long len;//链表中表元的数目
    void *(*dup)(void *ptr);
    void (*free)(void *ptr);
    void (*match)(void *ptr, void *key);
} feri_list;

feri_list *listcreate(void);
feri_list *listaddnodehead(feri_list *list, void *value);
feri_list *listaddnodetail(feri_list *list, void *value);
void listrewindhead(feri_list *list, feri_iter *li);
void listrewindtail(feri_list *list, feri_iter *li);
feri_listnode *listnext(feri_iter *iter);
feri_listnode *listfindkey(feri_list *list, void *key);
feri_list *listinsertnode(feri_list *list, feri_listnode *old_node, void *value, int after);
void listdelnode(feri_list *list, feri_listnode *node);
void listrelease(feri_list *list);//删除该链表包括哑结点
void listempty(feri_list *list);//清空链表,但是哑结点还在
feri_list *listchangenode(feri_list *list, feri_listnode *node, void *value);

#define FERI_START_HEAD 0
#define FERI_START_TAIL 1

#endif
#include "FERI_list.h"

#include <stdlib.h>
/*创建一个链表的哑结点*/
feri_list *listcreate(void)
{
    struct feri_list *list;
    if ((list = (feri_list *)malloc(sizeof(*list))) == NULL) {
        return NULL;
    }
    list->head = list->tail = NULL;
    list->len = 0;
    return list;
}
/*头插*/
feri_list *listaddnodehead(feri_list *list, void *value)
{
    feri_listnode *node;
    if ((node = (feri_listnode *)malloc(sizeof(*node))) == NULL) {
        return NULL;
    }
    node->value = value;
    if (list->len == 0) {
        list->head = list->tail = node;
        node->pre = node->nex = NULL;
    } else {
        node->pre = NULL;
        node->nex = list->head;
        list->head->pre = node;
        list->head = node;
    }
    list->len++;
    return list;
}
/*尾插*/
feri_list *listaddnodetail(feri_list *list, void *value)
{
    feri_listnode *node;
    if ((node = (feri_listnode *)malloc(sizeof(*node))) == NULL) {
        return NULL;
    } else {
        node->value = value;
        if (list->len == 0) {
            list->head = list->tail = node;
            node->nex = node->pre = NULL;
        } else {
            node->pre = list->tail;
            node->nex = NULL;
            list->tail->nex = node;
            list->tail = node;
        }
        list->len++;
    }
    return list;
}
/*迭代器条件控制,从头开始遍历*/
void listrewindhead(feri_list *list, feri_iter *li)
{
    li->next = list->head;
    li->direction = FERI_START_HEAD;
}
/*迭代器条件控制,从尾开始遍历*/
void listrewindtail(feri_list *list, feri_iter *li)
{
    li->next = list->tail;
    li->direction = FERI_START_TAIL;
}
/*迭代器控制临时索引结点向下一个结点跳转*/
feri_listnode *listnext(feri_iter *iter)
{
    feri_listnode *current = iter->next;
    if (current != NULL) {
        if (iter->direction == FERI_START_HEAD) {
            iter->next = current->nex;
        } else if (iter->direction == FERI_START_TAIL) {
            iter->next = current->pre;
        }
    }
    return current;
}
/*在某一个链表中查找*/
feri_listnode *listfindkey(feri_list *list, void *key)
{
    feri_listnode *node;
    feri_iter iter;
    listrewindhead(list, &iter);
    while ((node = listnext(&iter)) != NULL) {
        if (list->match) {
            if (1/*list->match(node->value, key)*/) {//void类型的值不能在上下文中转换为bool类型的值???????????
                return node;
            }
        } else {
            if (key == node->value) {
                return node;
            }
        }
    }
    return NULL;
}
/*在链表中插入*/
feri_list *listinsertnode(feri_list *list, feri_listnode *old_node, void *value, int after)
{
    feri_listnode *node;
    if ((node = (feri_listnode *)malloc(sizeof(*node))) == NULL) {
        return NULL;
    }
    node->value = value;
    if (after == 0) {//前叉
        node->nex = old_node;
        node->pre = old_node->pre;
        if (list->head == old_node) {
            list->head = node;
        }
    } else if (after == 1) {
        node->pre = old_node;
        node->nex = old_node->nex;
        if (list->tail == old_node) {
            list->tail = old_node;
        }
    }
    if (node->pre != NULL) {
        node->pre->nex = node;
    }
    if (node->nex != NULL) {
        node->nex->pre = node;
    }
    list->len++;
    return list;
}
/*删除链表中的某一个结点*/
void listdelnode(feri_list *list, feri_listnode *node)
{
    if (node->pre) {
        node->pre->nex = node->nex;
    } else {
        list->head = node->nex;
        node->nex->pre = NULL;
    }
    if (node->nex) {
        node->nex->pre = node->pre;
    } else {
        list->tail = node->pre;
        node->pre->nex = NULL;
    }
    if (list->free) {
        list->free(node->value);/
    }
    free(node);
    list->len--;
}

void listempty(feri_list *list){
    unsigned long len = list->len;
    feri_listnode *current,*tmp;
    current = list->head;
    while (len--) {
        tmp = current->nex;
        if (list->free) {
            list->free(current->value);
        }
        free(current);
        current = tmp;
    }
    list->head = list->tail = NULL;
    list->len = 0;
}

void listrelease(feri_list *list)
{
    listempty(list);
    free(list);
}
/*改变某一个结点的内容*/
feri_list *listchangenode(feri_list *list, feri_listnode *node, void *value)
{
    node->value = value;
    return list;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值