C语言双向链表模板

头文件

复制代码
#ifndef __DLIST_H__
#define __DLIST_H__

typedef struct dlist_node 
{
    struct dlist_node *next;
    struct dlist_node *prev;
} DlistNode;

#define DLIST_HEAD_INIT(name) { &(name), &(name) }

#define DLIST_HEAD(name) \
    struct dlist_node name = DLIST_HEAD_INIT(name)

static inline int dlist_empty(const struct dlist_node *head)
{
    return ((head->next == head) && (head->prev == head));
}

static inline void dlist_append(struct dlist_node *new_node, struct dlist_node *existing)
{
    existing->next->prev = new_node;
    new_node->next = existing->next;
    new_node->prev = existing;
    existing->next = new_node;
}

static inline void dlist_prepend(struct dlist_node *new_node, struct dlist_node *existing)
{
    existing->prev->next = new_node;
    new_node->next = existing;
    new_node->prev = existing->prev;
    existing->prev = new_node;
}

static inline void dlist_unlink(struct dlist_node *entry)
{
    entry->next->prev = entry->prev;
    entry->prev->next = entry->next;
    entry->next = 0;
    entry->prev = 0;
}

#undef offsetof
#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)

#define container_of(ptr, type, member) ({            \
        const typeof( ((type *)0)->member ) *__mptr = (ptr);    \
        (type *)( (char *)__mptr - offsetof(type,member) );})

#define dlist_entry(ptr, type, member) \
    container_of(ptr, type, member)

#define dlist_for_each_entry(pos, head, member)                \
    for (pos = dlist_entry((head)->next, typeof(*pos), member);    \
        &pos->member != (head);                     \
        pos = dlist_entry(pos->member.next, typeof(*pos), member))

#endif
复制代码

 

测试程序

复制代码
#include <stdio.h>
#include <stdlib.h>
#include "dlist.h"

struct myLinkList{
    struct dlist_node dlist;
    int to;
};

//初始化 DLIST_HEAD(glbList);
int main(int argc, char **argv){ int i =0; struct myLinkList *tmp; //添加元素 for(i = 0; i < 5; i++) { tmp = (struct myLinkList *)malloc(sizeof(struct myLinkList)); tmp->to = i; dlist_append((struct dlist_node *)tmp,&glbList); } //遍历链表,打印 dlist_for_each_entry(tmp, &glbList, dlist) { printf("%d\n",tmp->to); } printf("\n"); //删除元素 { dlist_for_each_entry(tmp, &glbList, dlist) { printf("%d\n",tmp->to); if(tmp->to == 3) { break; } } if ((struct dlist_node *) tmp != &glbList) { dlist_unlink((struct dlist_node *)tmp); free(tmp); } } //遍历链表,打印 printf("\n"); dlist_for_each_entry(tmp, &glbList, dlist) { printf("%d\n",tmp->to); } return 0; }
复制代码

 

posted @   roverqqq  阅读(50)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
点击右上角即可分享
微信分享提示