(二)Redis數據結構之鏈表

1 前言

    在上一篇文章中,概要介紹了Redis的第一種數據結構SDS(Simple Dynamic String)之後,本文將進一步介紹Redis中的另一種數據結構——鏈表。

 

2 什麼是鏈表

    鏈表,作爲數據結構中的基礎結構,理解起來非常簡單。以下是摘自百度百科中,對鏈表的定義。

    鏈表是一種物理存儲單元上非連續、非順序的存儲結構,數據元素的邏輯順序是通過鏈表中的指針鏈接次序實現的。鏈表由一系列結點(鏈表中每一個元素稱爲結點)組成,結點可以在運行時動態生成。每個結點包括兩個部分:一個是存儲數據元素的數據域,另一個是存儲下一個結點地址的指針域。

 

3 Redis鏈表的定義及實現

    在C語言中,沒有內置鏈表數據結構,所以,Redis構建了自己的鏈表實現。參考Redis源碼可知,鏈表的數據結構定義分成兩部分。

    第一部分:ListNode

    從上圖可知,Redis中的鏈表節點,採用雙端鏈表節點的設計方式,即每個節點都有指向自己前置節點和後置節點的指針域,同時包含節點本身的值域。

    而採用雙端鏈表,在之後實現對鏈表的讀寫上,能夠極大降低時間複雜度。

    第二部分:List

        從上圖可知,雙端鏈表的數據結構中,包括以下內容

        1 *head :指向鏈表頭結點的指針

        2 *tail: 指向鏈表表尾節點的指針

        3 *(*dup)(void *ptr):節點值複製函數

        4 (*free)(void *ptr):節點值釋放函數

        5 *match)(void *ptr, void *key):節點值對比函數

        6 len :鏈表包含的節點數量

    此外,雙端鏈表的數據結構定義中,還有一種輔助迭代器數據結構,用於迭代鏈表,即——雙端鏈表迭代器

    這裏說明一下迭代方向 direction值:adlist.h的頭文件中,預定義了兩個int類型變量,用於指示鏈表的迭代方向。

4 Redis中使用鏈表的優勢

    鏈表提供了高效的節點重排能力,以及順序性的節點訪問方式,並且可以通過增刪節點來靈活調整鏈表的長度。

    而Redis將鏈表數據結構定義成雙端鏈表,將具有以下性能優勢:

        1 雙端:每個鏈表節點都帶有prev和next指針,所以在獲取某個節點的前置節點和後置節點的複雜度都是O(1)

        2 帶表頭和表尾指針:通過list結構的head指針和tail指針,程序獲取鏈表表頭和表尾節點的時間複雜度爲O(1)

        3 自帶長度計數器:鏈表數據結構中的len屬性,用來對list持有的節點數進行統計,能夠在時間複雜度爲O(1)的前提下獲取鏈表中的節點數量。

        4 多態:鏈表的數據結構中,內置了三個函數(dup、free、match),同事鏈表節點使用void*指針來保存節點值,並且可以通過這三個函數設置特定的數據類型,所以,鏈表可以用來保存各種不同類型的值。

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