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 設計與實現 原樣搬過來的,很容易瞭解,講的特別好,主要是做個記錄,以後可以翻閱。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章