通用雙向連結串列的設計(參考Linux系統中的實現)
通常我們設計設計連結串列都是將資料域放在裡面,這樣每次需要使用連結串列的時候都需要實現一個連結串列,然後重新實現它的相關操作,這裡參考Linux系統中的設計實現了一個通用的雙向連結串列,只需要在你的結構裡面有一個這個連結串列的域,就可以使用連結串列的相關操作了。
注意:這個通用的雙向連結串列是參考Linux系統中的實現,它使用了typeof這個功能,所以有些編譯器可能不支援。我是再Windows系統中使用MinGW下使用GCC編譯的。
////////////////////////////////////////////////////////////////////////////////////////
// list.h
#ifndef _list_h
#define _list_h
typedef struct _list_head {
struct _list_head *prev,*next;
} list_head;
#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 list_empty(head) ( head->next==0&&head->prev==0 )
/* get the member of list object
* @ptr pointer to list_head
* @type the type of container which contains list_head field
* @memeber field name in the container
* @return return pointer to the container
*/
#define list_entry(ptr,type,member) container_of(ptr,type,member)
/* add a new node after `head`
*/
void list_add(list_head *head,list_head *node);
/* delete a node
*/
void list_del(list_head *node);
#endif
/////////////////////////////////////////////////////////
// list.c
#include "list.h"
/* add a new node after `head`
*/
void list_add(list_head *head,list_head *node) {
if(list_empty(head)) {
head->next = head;
head->prev = head;
}
node->next = head->next;
node->prev = head;
head->next->prev = node;
head->next = node;
}
/* delete a node
*/
void list_del(list_head *node) {
node->prev->next = node->next;
node->next->prev = node->prev;
}
///////////////////////////////////////////////////////////////////////////////
// test.c
#include <stdio.h>
#include <assert.h>
#include "list.h"
typedef struct _task {
int id;
list_head next;
} task;
#define task_next(t) ( container_of(t->next.next,task,next) )
void task_print(task *t) {
printf("#%d -> ",t->id);
}
void task_foreach(task *head,void (*callback)(task *)) {
task *p = head;
do {
callback(p);
p = task_next(p);
}
while (p!=head);
}
// use task like a list
void test_list() {
task t1={1,{0,0}},
t2={2,{0,0}},
t3={3,{0,0}},
t4={4,{0,0}},
t5={5,{0,0}};
list_add(&t1.next,&t2.next);
list_add(&t2.next,&t3.next);
list_add(&t3.next,&t4.next);
list_add(&t4.next,&t5.next);
task_foreach(&t1,task_print);
}
int main(int argc, char *argv[]) {
test_list();
return 0;
}
編譯執行
gcc test.c list.h list.c -o test
.\test.exe
下載程式碼
相關文章
- 連結串列-雙向通用連結串列
- 連結串列-雙向非通用連結串列
- 實現雙向連結串列
- 雙向連結串列的功能實現(初版
- Go實現雙向連結串列Go
- java實現雙向連結串列Java
- 資料結構(雙向連結串列的實現)資料結構
- 雙向迴圈連結串列的介面設計(初版
- 連結串列-雙向連結串列
- 雙向連結串列
- 資料結構-雙向連結串列(Python實現)資料結構Python
- 雙向連結串列介面設計(C語言)C語言
- Redis 原始碼解析之通用雙向連結串列(adlist)Redis原始碼
- 請使用 js 實現一個雙向連結串列JS
- 資料結構實驗之連結串列九:雙向連結串列資料結構
- 資料結構--陣列、單向連結串列、雙向連結串列資料結構陣列
- 單向迴圈連結串列的實現
- 單向連結串列介面設計
- 短連結系統的設計與實現
- 設計單向迴圈連結串列的介面
- go 實現單向連結串列Go
- 013 通過連結串列學習Rust之實現連結串列的通用函式Rust函式
- 013 透過連結串列學習Rust之實現連結串列的通用函式Rust函式
- 簡單介紹python中的單向連結串列實現Python
- 資料結構——雙向連結串列資料結構
- 結構與演算法(03):單向連結串列和雙向連結串列演算法
- DoublyLinkedList(雙向連結串列)——Javascript版JavaScript
- 資料結構_連結串列_單向迴圈連結串列 & 雙向連結串列的初始化、插入、刪除、修改、查詢列印(基於C語言實現)資料結構C語言
- 圖解雙連結串列(Java實現)圖解Java
- 資料結構之雙向連結串列資料結構
- 連結串列合併-排序-logo列印參考排序Go
- 資料結構-2.單向連結串列的實現資料結構
- 019 通過連結串列學Rust之雙連結串列實現PeekRust
- 019 透過連結串列學Rust之雙連結串列實現PeekRust
- 雙向連結串列 尾節點插入
- 【c# .net】雙向連結串列( LinkedList )C#
- 資料結構與演算法——連結串列 Linked List(單連結串列、雙向連結串列、單向環形連結串列-Josephu 問題)資料結構演算法
- 連結串列 - 單向連結串列