鏈表
1. 鏈表和鏈表節(jié)點的實現(xiàn)
每個鏈表節(jié)點使用一個adlist.h/listNode結構來表示
typedef struct listNode{
// 前置節(jié)點
struct listNode *prev;
// 后置節(jié)點
struct listNode *next;
// 節(jié)點的值
void *value;
}listNode;
使用adlist.h/list來持有鏈表的話,操作起來會更方便:
typedef struct list{
// 表頭節(jié)點
listNode *head;
// 表尾節(jié)點
listNode *tail;
// 鏈表所包含的節(jié)點數(shù)量
unsigned long len;
// 節(jié)點值復制函數(shù)
void *(*dup)(void *ptr);
// 節(jié)點值釋放函數(shù)
void (*free)(void *ptr);
// 節(jié)點值對比函數(shù)
int (*match)(void *ptr,void *key);
}list;
Redis鏈表實現(xiàn)的特性如下:
- 雙端:鏈表節(jié)點帶有prev和next指針,獲取某個節(jié)點的前置節(jié)點和后置節(jié)點的復雜度都是O(1)。
- 無環(huán):表頭節(jié)點的prev指針和表尾節(jié)點的next指針都指向NULL,對鏈表的訪問以NULL為終點。
- 帶表頭指針和表尾指針:通過list結構的head指針和tail指針,程序獲取鏈表的表頭節(jié)點和表尾節(jié)點的復雜度為O(1)。
- 帶鏈表長度計數(shù)器:程序使用list結構的len屬性來對list持有的鏈表節(jié)點進行計數(shù),程序獲取鏈表中節(jié)點數(shù)量的復雜度為O(1)。
- 多態(tài):鏈表節(jié)點使用void*指針來保存節(jié)點值,并且可以通過list結構的dup、free、match三個屬性為節(jié)點值設置類型特定函數(shù),所以鏈表可以用于保存各種不同類型的值。

由list結構和listNode結構組成的鏈表
2. 鏈表和鏈表節(jié)點的API
| 函數(shù) | 作用 | 時間復雜度 |
|---|---|---|
| listSetDupMethod | 將給定的函數(shù)設置為鏈表的節(jié)點值復制函數(shù) | 復制函數(shù)可以通過鏈表的dup屬性直接獲得,O(1) |
| listGetDupMethod | 返回鏈表當前正在使用的節(jié)點值復制函數(shù) | O(1) |
| listSetFreeMethod | 將給定的函數(shù)設置為鏈表的節(jié)點值釋放函數(shù) | 釋放函數(shù)可以通過鏈表的free屬性直接獲得,O(1) |
| listGetFreeMethod | 返回鏈表當前正在使用的節(jié)點值釋放函數(shù) | O(1) |
| listSetMatchMethod | 將給定的函數(shù)設置為鏈表的節(jié)點值對比函數(shù) | 對比函數(shù)可以通過鏈表的match屬性直接獲得,O(1) |
| listGetMatchMethod | 返回鏈表當前正在使用的節(jié)點值對比函數(shù) | O(1) |
| listLength | 返回鏈表的長度(包含了多少個節(jié)點) | 鏈表長度可以通過鏈表的len屬性直接獲得,O(1) |
| listFirst | 返回鏈表的表頭節(jié)點 | 表頭節(jié)點可以通過鏈表的head屬性直接獲得,O(1) |
| listLast | 返回鏈表的表尾節(jié)點 | 表尾節(jié)點可以通過鏈表的tail屬性直接獲得,O(1) |
| listPrevNode | 返回給定節(jié)點的前置節(jié)點 | 前置節(jié)點可以通過節(jié)點的prev屬性直接獲得,O(1) |
| listNextNode | 返回給定節(jié)點的后置接地那 | 后置節(jié)點可以通過節(jié)點的next屬性直接獲得,O(1) |
| listNodeValue | 返回給定節(jié)點目前正在保存的值 | 節(jié)點值可以通過接地那的value屬性直接獲得,O(1) |
| listCreate | 創(chuàng)建一個不包含任何節(jié)點的新鏈表 | O(1) |
| listAddNodeHead | 將一個包含給定值的新節(jié)點添加到給定鏈表的表頭 | O(1) |
| listAddNodeTail | 將一個包含給定值的新節(jié)點添加到給定鏈表的表尾 | O(1) |
| listInsertNode | 將一個包含給定值的新節(jié)點添加到給定節(jié)點的之前或之后 | O(1) |
| listSearchKey | 查找并返回鏈表中包含給定值的節(jié)點 | O(N),N為鏈表長度 |
| listIndex | 返回鏈表在給定索引上的節(jié)點 | O(N),N為鏈表長度 |
| listDelNode | 從鏈表中刪除給定節(jié)點 | O(N),N為鏈表長度 |
| listRotate | 將鏈表的表尾節(jié)點彈出,然后將被彈出的節(jié)點插入到鏈表的表頭,稱為新的表頭節(jié)點 | O(N),N為鏈表長度 |
| listDup | 復制一個給定鏈表的副本 | O(N),N為鏈表長度 |
| listRelease | 釋放給定鏈表,以及鏈表中的所有節(jié)點 | O(N),N為鏈表長度 |