通用雙向連結串列的設計(參考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
下載程式碼
相關文章
- MYSQL INNODB 中通用雙向連結串列的實現MySql
- C++實現通用雙向連結串列C++
- Java雙向連結串列的實現Java
- Linux核心連結串列-通用連結串列的實現Linux
- 實現雙向連結串列
- 雙向連結串列的功能實現(初版
- Go實現雙向連結串列Go
- java實現雙向連結串列Java
- javascript中的連結串列結構—雙向連結串列JavaScript
- 資料結構(雙向連結串列的實現)資料結構
- 雙向迴圈連結串列的介面設計(初版
- JAVA基礎:語言中連結串列和雙向連結串列的實現(轉)Java
- 雙向連結串列
- 雙向連結串列介面設計(C語言)C語言
- python 資料結構之雙向連結串列的實現Python資料結構
- 資料結構-雙向連結串列(Python實現)資料結構Python
- Redis 原始碼解析之通用雙向連結串列(adlist)Redis原始碼
- 資料結構實驗之連結串列九:雙向連結串列資料結構
- 雙向迴圈連結串列基本操作的實現(C語言)C語言
- 資料結構--陣列、單向連結串列、雙向連結串列資料結構陣列
- Linux 核心資料結構:雙向連結串列Linux資料結構
- 雙向連結串列的建立及基本操作
- go 實現單向連結串列Go
- 單向連結串列介面設計
- 資料結構——雙向連結串列資料結構
- 資料結構:雙向連結串列資料結構
- 結構與演算法(03):單向連結串列和雙向連結串列演算法
- C語言之雙向連結串列C語言
- 設計單向迴圈連結串列的介面
- 短連結系統的設計與實現
- 雙向連結串列的操作(插入和刪除)
- 013 通過連結串列學習Rust之實現連結串列的通用函式Rust函式
- 013 透過連結串列學習Rust之實現連結串列的通用函式Rust函式
- 簡單介紹python中的單向連結串列實現Python
- 資料結構之雙向連結串列資料結構
- C 語言使用非迴圈雙向連結串列實現佇列佇列
- 實戰資料結構(5)_雙向迴圈連結串列的基本操作資料結構
- C++中的連結串列類的設計C++