1. 程式人生 > >Redis設計與實現之連結串列--閱讀筆記

Redis設計與實現之連結串列--閱讀筆記

前言

連結串列提供了高效的節點重排能力,以及順序性的節點訪問方式,連結串列在 Redis 中的應用很廣泛,比如列表鍵的底層實現之一就是連結串列,除此之外,釋出與訂閱、慢查詢、監視器等功能也用到了連結串列,Redis 伺服器本身使用連結串列儲存多個客戶端的狀態資訊,使用連結串列構建客戶端輸出緩衝區。

連結串列的底層實現

學習過演算法的同學都知道資料結構中的連結串列的相關概念了,這裡簡單介紹一下連結串列的資料結構:

連結串列是常見的基礎資料結構,是一種線性表,但是並不會按線性的順序儲存資料,而是在每一個節點裡存到下一個節點的指標(Pointer)。由於不必須按順序儲存,連結串列在插入的時候可以達到O(1)的複雜度,比另一種線性表 順序錶快得多,但是查詢一個節點或者訪問特定編號的節點則需要O(n)的時間,而順序表相應的時間複雜度分別是O(logn)和O(1)。(來源於維基百科)

幾種常用的連結串列

先來看看一個連結串列節點的資料結構:

typedef struct listNode {
    // 前置節點 
    struct listNode *prev; 
    // 後置節點 
    struct listNode *next; 
    // 節點的值 
    void *value;
}listNode;

多個 listNode (連結串列節點)通過 prev 和 next 指標組成雙向連結串列

連結串列

下面使用 list 資料結構來管理連結串列:

typedef struct list {
    // 表頭節點 
	listNode *head; 
	// 表尾節點 
	listNode *
tail; // 連結串列所包含的節點數量 unsigned long len; // 節點值複製函式 void *(*dup)(void *ptr); // 節點值釋放函式 void *(*free)(void *ptr); // 節點值對比函式 void *(*match)(void *ptr, void *key); }list;

list 結構為連結串列提供了表頭指標head, 表尾指標tail,以及連結串列長度計數器len, 而dup、free 和match 函式的作用如下:

  • dup 函式用於複製連結串列節點所儲存的值
  • free 函式用於釋放連結串列節點所儲存的值
  • match 函式用於對比連結串列節點所儲存的值與另外一個輸入值是否相等

list 結構與 listNode 結構組成的連結串列

list 結構與 listNode 組成的連結串列

Redis 連結串列特點總結

  • 雙向: 連結串列節點都有 prev 和 next 指標,可以獲取某個節點的前置節點和後置節點,複雜度為O(1)
  • 無環:上面圖片顯示,表頭節點的 prev 指標和表尾節點的 next 指標都指向 NULL
  • 帶表頭指標和表尾指標: 通過 list 結構的 head 和 tail 指標,獲取表頭節點和表尾節點的複雜度為O(1)
  • 帶連結串列長度計數器:通過 list 結構的 len 欄位記錄了 連結串列中的連結串列節點(listNode)數,獲取連結串列長度的複雜度為O(1)
  • 多型:連結串列節點使用 void * 指標來儲存節點值,可以通過 list 結構的 dup、free和match 屬性為節點值設定型別特定函式,所有連結串列可用於儲存不同型別的值

這章內容比較少,基本就是 Redis 設計與實現 原樣搬過來的,很容易瞭解,講的特別好,主要是做個記錄,以後可以翻閱。