1. 程式人生 > 其它 >Redis底層資料結構之雙端連結串列

Redis底層資料結構之雙端連結串列

技術標籤:Redis

連結串列這種資料結構相信大家也不陌生,有很多型別,比如單向連結串列,雙向連結串列,迴圈連結串列等,連結串列相對於陣列來說,一是不需要連續的記憶體塊地址,二是刪除和插入的時間複雜度是 O(1) 級別的,非常的高效,但比不上陣列的隨機訪問查詢方式。

一樣的那句話,沒有最好的資料結構,只有恰到好處的資料結構,比如我們後面要介紹的更高層次的資料結構,字典,它的底層其實就依賴的連結串列規避雜湊衝突,具體的我們後面再說。

redis 中藉助 C 語言實現了一個雙向連結串列結構:

struct listNode{
    // 前一個節點的指標
    struct listNode *prev;
// 後一個節點的指標 struct listNode *next; // 節點值 void *value; };

prev 指標指向前一個節點,next 指標指向後一個節點,value 指向當前節點對應的資料物件。我盜一張圖描述整個串聯起來的連結串列結構:
在這裡插入圖片描述
雖然我通過連結串列的第一個頭節點就可以遍歷整個連結串列,但在 redis 向上封裝了一層結構,專門用於表示一個連結串列結構:

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

head 指向連結串列的頭節點,tail 指向連結串列的尾節點,dup 函式用於連結串列轉移複製時對節點 value 拷貝的一個實現,一般來說用等於號足以,但某些特殊情況下可能會用到節點轉移函式,預設可以給這個函式賦值 NULL 即表示使用等於號進行節點轉移。free 函式用於釋放一個節點所佔用的記憶體空間,預設賦值 NULL 的話,即使用 redis 自帶的 zfree 函式進行記憶體空間釋放,

Redis連結串列的特性和優點:

由於是雙向連結串列,具有前後節點的指標引用,所以對獲取這兩個節點的時間複雜度為O(1)。
通過連結串列長度len屬性,獲取長度的時間複雜度為O(1)。
由於節點值是一個指標,所以value可以指定任何型別。
頭節點的前指標和尾結點的後指標都為NULL,是無環的