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; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了