Redis原理再學習 鍊錶 list

2022-09-19 12:36:14 字數 3380 閱讀 3985

鍊錶(linked list)是一種基礎資料結構,是一種線性表,但是不會按照線性表的順序儲存資料,而是在每乙個節點裡存到下乙個節點的指標。

鍊錶插入節點時是 o(1) 複雜度,比線性表順序表快。

鍊錶訪問節點或訪問特殊節點時是 o(n) 複雜度時間,順序表相應複雜度是 o(logn)和o(1)。

--- 維基百科-鍊錶

下面看看最經常用到的 3 種鍊錶。

單向鍊錶:

雙向鍊錶:

迴圈鍊錶:

說明:以上來自維基百科-鍊錶

redis3.0 中使用的鍊錶結構是雙向鍊錶。看看它的結構定義,在檔案 adlist.h 中。

// 

/* node, list, and iterator are the only data structures used currently. */

typedef struct listnode listnode;

上面 listnode 可以組成乙個鍊錶結構,如下圖:

上面的 listnode 也可以組成乙個鍊錶,但是操作起來不是很方便。為了更方便的操作定義了乙個 list 的鍊錶。

// 

typedef struct list list;

乙個鍊錶 list 長度為 4 的結構示意圖如下:

redis 定義的雙向鍊錶的好處:

獲取某節點的前置節點和後置節點的複雜度為o(1),因為鍊錶帶有 prev 和 next 指標。

獲取煉表頭節點和尾節點的複雜度為o(1),因為鍊錶帶有表頭指標 head 和表尾指標 tail。

計算鍊錶節點數量的複雜度為o(1),因為有 len 屬性。

每個節點可以儲存任意值,因為是 *void 定義值型別。

把一些對list和listnode查詢值和賦值封裝成巨集操作:

// 

/* functions implemented as macros */

#define listlength(l) ((l)->len) // 獲取節點數量

#define listfirst(l) ((l)->head) // 獲取鍊錶頭部節點

#define listlast(l) ((l)->tail) // 獲取鍊錶尾部節點

#define listprevnode(n) ((n)->prev)

#define listnextnode(n) ((n)->next)

#define listnodevalue(n) ((n)->value)

#define listsetdupmethod(l,m) ((l)->dup = (m))

#define listsetfreemethod(l,m) ((l)->free = (m))

#define listsetmatchmethod(l,m) ((l)->match = (m))

#define listgetdupmethod(l) ((l)->dup)

#define listgetfree(l) ((l)->free)

#define listgetmatchmethod(l) ((l)->match)

鍊錶操作的函式原型:

// 

/* prototypes */

list *listcreate(void); // 初始化鍊錶

void listrelease(list *list); // 釋放煉表頭和鍊錶

list *listaddnodehead(list *list, void *value); // 將值新增到鍊錶的頭部

list *listaddnodetail(list *list, void *value); // 將值新增到鍊錶的尾部

list *listinsertnode(list *list, listnode *old_node, void *value, int after);

void listdelnode(list *list, listnode *node);

listiter *listgetiterator(list *list, int direction);

listnode *listnext(listiter *iter);

void listreleaseiterator(listiter *iter);

list *listdup(list *orig);

listnode *listsearchkey(list *list, void *key);

listnode *listindex(list *list, long index);

void listrewind(list *list, listiter *li);

void listrewindtail(list *list, listiter *li);

void listrotate(list *list);

listcreate函式**:

建立乙個新的鍊錶 list,給 list 各個成員賦值預設值。

// 

/* create a new list. the created list can be freed with

* alfreelist(), but private value of every node need to be freed

* by the user before to call alfreelist().

* * on error, null is returned. otherwise the pointer to the new list. */

list *listcreate(void)

redis.io

github redis3.0-list

github redis3.0-list

Redis 鍊錶

定義 每個鍊錶節點使用乙個 adlist.h listnode 結構來表示 typedef struct listnode listnode adlist.h list 列表結構 typedef struct list list 特性 redis 的鍊錶實現的特性可以總結如下 雙端 鍊錶節點帶有 p...

Redis學習 2 鍊錶(list)

鍊錶的使用十分廣泛,甚至很多高階程式語言都內建了這種資料結構。但是c語言卻不沒有。不過c語言編寫的redis卻自己構建了鍊錶這種資料結構在自己內部。127.0.0.1 6379 lpush list a b c d e 向鍊錶中新增a b c d e f integer 5 此時鍊錶中的資料個數 1...

Redis學習筆記(二) 鍊錶

鍊錶提供了高效的節點重排能力,以及順序性的節點訪問方式,並且可以通過增刪節點來靈活地調整鍊錶的長度。redis中煉表應用廣泛,如list中就使用了鍊錶。每乙個鍊錶節點使用listnode結構標識 雙向鍊錶 typedef struct listnode typedef struct list red...