鍊錶(linked list)是一種基礎資料結構,是一種線性表,但是不會按照線性表的順序儲存資料,而是在每乙個節點裡存到下乙個節點的指標。下面看看最經常用到的 3 種鍊錶。鍊錶插入節點時是 o(1) 複雜度,比線性表順序表快。
鍊錶訪問節點或訪問特殊節點時是 o(n) 複雜度時間,順序表相應複雜度是 o(logn)和o(1)。
--- 維基百科-鍊錶
單向鍊錶:
雙向鍊錶:
迴圈鍊錶:
說明:以上來自維基百科-鍊錶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...