linux核心鍊錶在/usr/src/linux-headers-***/include/linux/list.h中可以看到,其中***為核心版本號。我們可以採用核心鍊錶的方式實現我們自己的資料結構。
核心鍊錶節點定義的結構體中只包含了指標域,
struct list_head ;
那麼資料放在**呢?實際上核心鍊錶是通過兩層結構體的方式實現的,大結構體裡面包含資料域和乙個小結構體,該小結構體也就是上面的節點,鍊錶通過小結構體聯絡起來,然後訪問資料時通過container_of巨集從小結構體轉向大結構體。#define offset_of(type, member) \
((size_t)(&(((type *)0)->member)))
#define container_of(ptr, type, member) \
(type *)((size_t)(ptr) - offset_of(type, member))
然後核心鍊錶的實現採用了內聯函式提高效率,相對於普通雙鏈表,核心鍊錶多了一步大小結構體轉換的過程,其他的都差不多。下面是簡易的lish.h#pragma once
struct list_head ;
#define list_head_init(head) \
struct list_head (head) =
static inline void list_head_init(struct list_head *head)
static inline void __list_add(struct list_head *new, struct list_head *prev, struct list_head *next)
static inline void list_add(struct list_head *new, struct list_head *head)
static inline void list_add_tail(struct list_head *new, struct list_head *head)
static inline void node_del(struct list_head *node)
static inline void node_del_init(struct list_head *node)
#define list_for_each(cur, head) \
for ((cur) = (head)->next; (cur) != (head); (cur) = (cur)->next)
#define offset_of(type, member) \
((size_t)(&(((type *)0)->member)))
#define container_of(ptr, type, member) \
(type *)((size_t)(ptr) - offset_of(type, member))
#define list_for_each_reverse(cur, head) \
for (cur = (head)->prev; cur != (head); cur = (cur)->prev)
#define list_for_each_continue(cur, head) \
for (cur = (cur)->next; cur != (head); cur = (cur)->next)
#define list_for_each_from(cur, head) \
for ( ; cur != (head); cur = (cur)->next)
/*直接遍歷大結構體(宿主結構)*/
#define list_for_each_entry(pos, head, member) \
for (pos = container_of((head)->next, typeof(*pos), member); &(pos)->member != head; \
pos = container_of((pos)->member.next, typeof(*pos), member))
簡單的測試#include #include "list.h"
struct data_info ;
int main(void)
, ,
, };
int i = 0;
for (; i < sizeof(s) / sizeof(s[0]); i++)
struct list_head *cur = null;
struct data_info *pa = null;
list_for_each(cur, &head)
return 0;
}
演算法筆記 資料結構 鍊錶
鍊錶節點一般有兩部分組成,即資料域和指標域 struct node 一般說來,資料域放節點要儲存的資料,而指標域指向下乙個結點的位址,這樣就會產生從某個結點開始的 由指標連線的一條鏈式結構,即鍊錶。而以鍊錶是否存在頭結點,又可以把鍊錶分為帶頭結點的鍊錶和不帶頭結點的鍊錶。頭結點一般成為head,且其...
考研筆記 資料結構之鍊錶
線性表的鏈式儲存結構的特點是用一組任意的儲存單元儲存線性表的資料元素。這組儲存單元可以是連續的,也可以是不連續的 線性表的鏈式儲存是一種非隨機儲存結構,但是方便插入和刪除。單鏈表的每個結點中只包含乙個指標域,指向下乙個結點。typedef struct slnode node,linklist 構造...
學習筆記 資料結構04 單迴圈鍊錶
將單鏈表中終端結點的指標端由空指標改為指向頭結點,就使整個單鏈表形成乙個環,這種頭尾相接的單鏈表稱為單迴圈鍊錶,簡稱迴圈鍊錶 circular linked list 它解決了乙個很麻煩的問題 如何從當中乙個結點出發,訪問到鍊錶的全部結點。為了使空鍊錶與非空煉表處理一致,我們通常設乙個頭結點,當然這...