【Redis基本數據結構】鏈表實現


做爲一種經常使用數據結構,鏈表內置在不少高級編程語言裏, 由於 C 語言沒有內置這種數據結構, Redis 構建了本身的鏈表實現.git

鏈表在 Redis 中的應用十分普遍, 好比列表鍵的底層實現之一就是鏈表. 當一個列表鍵包含了數量較多的元素,或者列表中包含的元素都是比較長的字符串時, Redis 就會使用鏈表做爲列表鍵的底層實現.
<!-- more -->
除了列表鍵以外, 發佈與訂閱、慢查詢、監視器等功能也用到了鏈表.還有使用鏈表來構建客戶端輸出緩衝區等.github

對於鏈表的定義和相關算法,不少算法書籍已經作了詳細的講解.這裏只對 Redis 中鏈表的實現作介紹.算法

鏈表和鏈表節點的實現

每一個鏈表節點使用一個 listNode 結構來表示:編程

// file: adlist.h
typedef struct listNode {
    struct listNode *prev;  // 前置節點
    struct listNode *next;  //後置節點
    void *value;            //節點的值
} ListNode;

多個鏈表節點經過 prevnext 組成雙端鏈表,
Redis 使用 list 結構來管理鏈表:數據結構

typedef struct list {
    listNode *head;         //表頭節點
    listNode *tail;         //表尾節點
    unsigned long len;      //鏈表的節點數量
    void *(*dup) (void *ptr);   //節點值複製函數
    void (*free)(void *ptr);    //節點值釋放函數
    int (*match)(void *ptr, void *key); //節點值對比函數
} list;

下圖是由一個 lsit 結構和三個 ListNode 結構組成的鏈表.編程語言

此處輸入圖片的描述

鏈表實現特性

Redis 的鏈表實現特性能夠總結以下:函數

  • 雙端: 由於帶有 prevnext 指針,獲取某個節點的前置節點和後置節點的複雜度都是$O(1)$spa

  • 無環: 表頭的 prev 指針和表尾的 next 指針均指向 NULL, 對鏈表的訪問以 NULL 結束.指針

  • 帶表頭指針和表尾指針: 經過 list 結構獲取表頭和表尾的複雜度爲$ O(1)$.code

  • 帶鏈表長度計數器: list 結構的 len 屬性對鏈表節點的長度計數, 獲取鏈表中節點的數量複雜度爲$ O(1)$

  • 多態: 鏈表節點使用 void * 指針來保存節點值, 而且能夠經過 list 結構的 dupfreematch 三個屬性爲節點值設置類型特定函數.鏈表能夠用於保存各類不一樣類型的值.

個人博客: http://ygmyth.github.io

相關文章
相關標籤/搜索