「Redis設計與實現(xiàn)」鏈表篇

鏈表簡介

鏈表提供了高效的節(jié)點重排能力, 以及順序性的節(jié)點訪問方式, 并且可以通過增刪節(jié)點來靈活地調(diào)整鏈表的長度。作為一種常用數(shù)據(jù)結構厌衙, 鏈表內(nèi)置在很多高級的編程語言里面, 因為 Redis 使用的 C 語言并沒有內(nèi)置這種數(shù)據(jù)結構绞绒, 所以 Redis 構建了自己的鏈表實現(xiàn)迅箩。

鏈表及鏈表節(jié)點的實現(xiàn)

  • 每個鏈表節(jié)點使用一個adlist.h/listNode結構來表示
typedef struct listNode {
    struct listNode *prev; /* 前置節(jié)點 */
    struct listNode *next; /* 后置節(jié)點 */
    void *value; /* 節(jié)點值 */
} listNode;
  • Reids還定義了鏈表結構,用于持有鏈表
typedef struct list {
    listNode *head; /* 表頭結點 */
    listNode *tail; /* 表尾結點 */
    void *(*dup)(void *ptr); /* 節(jié)點復制函數(shù) */
    void (*free)(void *ptr); /* 節(jié)點釋放函數(shù) */
    int (*match)(void *ptr, void *key); 
    unsigned long len; /* 鏈表節(jié)點數(shù)量 */
} list;

list 結構為鏈表提供了表頭指針 head 处铛、表尾指針 tail 饲趋, 以及鏈表長度計數(shù)器 len , 而 dup 撤蟆、 free 和 match 成員則是用于實現(xiàn)多態(tài)鏈表所需的類型特定函數(shù):

  1. dup 函數(shù)用于復制鏈表節(jié)點所保存的值奕塑;
  2. free 函數(shù)用于釋放鏈表節(jié)點所保存的值;
  3. match 函數(shù)則用于對比鏈表節(jié)點所保存的值和另一個輸入值是否相等家肯。

如圖是由一個list結構和三個listNode結構組成的鏈表


list持有l(wèi)istNode示例.png

這樣定義好處是

  1. 快速獲取鏈表的頭尾
  2. 快速查詢鏈表的節(jié)點數(shù)龄砰,像動態(tài)字符串sdshr里的len那樣,不用遍歷全部字符就可以獲取字符串的長度讨衣,這里也類似换棚。
  • adlist.h/listIter還定義了迭代器
typedef struct listIter {
    listNode *next; /* 當前迭代到的節(jié)點 */
    int direction; /* 迭代方向 */
} listIter;
/* Directions for iterators 
 *
 * 迭代器進行迭代的方向
 */
// 從表頭向表尾進行迭代
#define AL_START_HEAD 0
// 從表尾到表頭進行迭代
#define AL_START_TAIL 1

可以這樣迭代

iter = listGetIterator(list, AL_START_HEAD);
while ((node = listNext(iter)) != NULL) {
    doSomethingWith(node);
}

鏈表和鏈表節(jié)點的API

函數(shù) 作用 時間復雜度
listSetDupMethod 將給定的函數(shù)設置為鏈表的節(jié)點值復制函數(shù)。 O(1)
listGetDupMethod 返回鏈表當前正在使用的節(jié)點值復制函數(shù)反镇。 復制函數(shù)可以通過鏈表的 dup 屬性直接獲得固蚤, O(1)
listSetFreeMethod 將給定的函數(shù)設置為鏈表的節(jié)點值釋放函數(shù)。 O(1)
listGetFree 返回鏈表當前正在使用的節(jié)點值釋放函數(shù)歹茶。 釋放函數(shù)可以通過鏈表的 free 屬性直接獲得夕玩, O(1)
listSetMatchMethod 將給定的函數(shù)設置為鏈表的節(jié)點值對比函數(shù)。 O(1)
listGetMatchMethod 返回鏈表當前正在使用的節(jié)點值對比函數(shù)惊豺。 對比函數(shù)可以通過鏈表的 match 屬性直接獲得燎孟, 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é)點可以通過節(jié)點的 next 屬性直接獲得, O(1)
listNodeValue 返回給定節(jié)點目前正在保存的值磁浇。 節(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(1)
listRotate 將鏈表的表尾節(jié)點彈出,然后將被彈出的節(jié)點插入到鏈表的表頭告匠, 成為新的表頭節(jié)點戈抄。 O(1)
listDup 復制一個給定鏈表的副本。 O(N) 后专, N 為鏈表長度
listRelease 釋放給定鏈表划鸽,以及鏈表中的所有節(jié)點。 O(N) 戚哎, N 為鏈表長度
最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末裸诽,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子型凳,更是在濱河造成了極大的恐慌丈冬,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,839評論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件甘畅,死亡現(xiàn)場離奇詭異殷蛇,居然都是意外死亡,警方通過查閱死者的電腦和手機橄浓,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,543評論 2 382
  • 文/潘曉璐 我一進店門粒梦,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人荸实,你說我怎么就攤上這事匀们。” “怎么了准给?”我有些...
    開封第一講書人閱讀 153,116評論 0 344
  • 文/不壞的土叔 我叫張陵泄朴,是天一觀的道長重抖。 經(jīng)常有香客問我,道長祖灰,這世上最難降的妖魔是什么钟沛? 我笑而不...
    開封第一講書人閱讀 55,371評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮局扶,結果婚禮上恨统,老公的妹妹穿的比我還像新娘。我一直安慰自己三妈,他們只是感情好畜埋,可當我...
    茶點故事閱讀 64,384評論 5 374
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著畴蒲,像睡著了一般悠鞍。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上模燥,一...
    開封第一講書人閱讀 49,111評論 1 285
  • 那天咖祭,我揣著相機與錄音,去河邊找鬼蔫骂。 笑死心肪,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的纠吴。 我是一名探鬼主播硬鞍,決...
    沈念sama閱讀 38,416評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼戴已!你這毒婦竟也來了固该?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 37,053評論 0 259
  • 序言:老撾萬榮一對情侶失蹤糖儡,失蹤者是張志新(化名)和其女友劉穎伐坏,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體握联,經(jīng)...
    沈念sama閱讀 43,558評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡桦沉,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,007評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了金闽。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片纯露。...
    茶點故事閱讀 38,117評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖代芜,靈堂內(nèi)的尸體忽然破棺而出埠褪,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 33,756評論 4 324
  • 正文 年R本政府宣布钞速,位于F島的核電站贷掖,受9級特大地震影響,放射性物質發(fā)生泄漏渴语。R本人自食惡果不足惜苹威,卻給世界環(huán)境...
    茶點故事閱讀 39,324評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望驾凶。 院中可真熱鬧牙甫,春花似錦、人聲如沸狭郑。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,315評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽翰萨。三九已至,卻和暖如春糕殉,著一層夾襖步出監(jiān)牢的瞬間亩鬼,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,539評論 1 262
  • 我被黑心中介騙來泰國打工阿蝶, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留雳锋,地道東北人。 一個月前我還...
    沈念sama閱讀 45,578評論 2 355
  • 正文 我出身青樓羡洁,卻偏偏與公主長得像玷过,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子筑煮,可洞房花燭夜當晚...
    茶點故事閱讀 42,877評論 2 345

推薦閱讀更多精彩內(nèi)容