本發明屬于計算機存儲技術領域,更具體地,涉及一種多層鏈接分離的skiplist構造方法及系統。
背景技術:
跳躍表skiplist是一種隨機化的數據結構,基于并聯的有序鏈表,其搜索的時間復雜度為O(logn),n為skiplist中的元素個數。skiplist以其實現簡單、快速高效而被廣泛應用于鍵值存儲系統或內存數據庫系統,如redis、leveldb等。
相比有序單鏈表,skiplist查找效率隨skiplist容量呈對數增長,性能遠超過有序單鏈表的線性擴展性能,雖然典型的樹結構,如二叉有序樹(Binary Search Tree,BST)亦可達到skiplist的查找、插入效率,但是維持樹的平衡需要進行復雜的操作,如平衡二叉樹(Balanced Binary Tree,AVL)、紅黑樹(Red Black Tree,RBT)的插入操作需要定位元素位置、插入元素、以及旋轉,其中后續的旋轉操作用于保證樹的平衡,不至于樹的結構退化成有序單鏈表,由于該操作視插入元素的位置來決定如何調整鏈接關系導致樹的結構的分析以及維持變得非常復雜。
skiplist構造的典型實現包括初始化和插入兩個階段,其中,在skiplist初始化階段定義skiplist的高度閾值,確定節點高度增長的概率因子p以及構造頭節點;在插入階段,按照特定的方案將元素封裝成節點按元素非遞減的順序插入到skiplist,同時保證從底層到頂層各層鏈表的節點數目按照概率因子p等比遞減。
現有的skiplist構造方案主要包括兩種,其一,隨機構造方案,即每次隨機生成節點高度,然后將節點插入鏈表,由于待插節點的高度及大小在插入之前是隨機的,故這種情況會導致構造的skiplist相鄰層的節點分布不能嚴格符合概率比,存在位于高層鏈表的節點極其稀少,與低層的概率比嚴重偏離概率因子p的最壞情形,同時無法保證各層鏈表中節點的跨度均勻;其二,確定性構造方案,每次插入都根據固定算法對整個結構進行重構,從而保證skiplist結構均勻,以及高度和跨度最優化,但是重構需要較長時間而且過程中整個數據結構被鎖住,導致并行性能差。
技術實現要素:
針對現有技術的以上缺陷或改進需求,本發明提供了一種多層鏈接分離的skiplist構造方法及系統,將插入操作過程中的多層有序鏈表鏈接開銷分攤到查找操作過程的各個有序單鏈表插入鏈接過程中,相比skiplist的隨機構造方案,僅在各層查找中對滿足跨度要求的節點增加高度,即將節點鏈接到比當前節點高度更高一層的鏈表中,單個元素的鏈接操作時間開銷為O(1),而插入操作只需將元素插入到底層有序單鏈表中,降低了多層鏈表間的耦合關系,從而提高skiplist的并發插入性能;此外,相比skiplist的確定性構造方案,插入元素后無需為了完善skiplist而重構整個數據結構,從而避免重構skiplist導致的skiplist不可用的情形發生。由此解決現有skiplist構造方案中,隨機構造方案構造的skiplist相鄰層的節點分布不能嚴格符合概率比、無法保證各層鏈表中節點的跨度均勻以及確定性構造方案需要對整個結構進行重構的技術問題。
為實現上述目的,按照本發明的一個方面,提供了一種多層鏈接分離的skiplist構造方法,包括:
(1)單個元素的查詢,其子步驟為:
(1-1)設置當前掃描的層次為skiplist當前的最大高度,初始化計步器值為0,將當前所處的位置記為掃描點,將當前掃描的層次記為掃描層,將當前掃描的單鏈表記為掃描鏈;
(1-2)從當前掃描的單鏈表開始按前進指針的方向掃描,判斷待插入的目標元素與掃描點處的元素的大小關系,若掃描點處的元素與目標元素相等,則返回,結束本次單個元素的插入操作,繼續下一個元素的插入操作,若掃描點處的元素小于目標元素,則執行步驟(1-3),若掃描點處的元素大于目標元素,則執行步驟(1-4);
(1-3)計步器增加1,并判斷計步器中的計數值是否達到預設值,其中,預設值為概率因子p的倒數,若計步器的計數值達到預設值,則將掃描點處的節點高度增加1,即將該掃描點處的節點鏈接到掃描層的上面一層的鏈表中,同時計步器置0,掃描點向前移動,若計步器的計數值沒有達到預設值,則執行步驟(1-2);
(1-4)判斷當前掃描的層次是否為最底層,若是最底層,則返回掃描點的后退一個位置,并記為插入點,若不是最底層,則將掃描點后退一步,掃描層下移一層,從后退之后的掃描點處的節點開始,轉至執行步驟(1-2);
(2)單個元素插入:若skiplist中不存在目標元素,則在最底層的有序單鏈表中將該目標元素插入到步驟(1)返回的插入點之后,且將節點高度設為1。
優選地,在步驟(1)之前,所述方法還包括:設置概率因子p和skiplist節點所能達到的高度閥值;分配skiplist對象,skiplist具有當前高度和頭結點兩個屬性,并初始化頭結點,以高度閥值作為頭節點的高度,分配前進鏈接指針數組,指針數組的每個元素指向空指針。
按照本發明的另一方面,提供了一種多層鏈接分離的skiplist構造系統,包括:
查詢模塊,用于單個元素的查詢,其包括的子模塊為:
設置模塊,用于設置當前掃描的層次為skiplist當前的最大高度,初始化計步器值為0,將當前所處的位置記為掃描點,將當前掃描的層次記為掃描層,將當前掃描的單鏈表記為掃描鏈;
第一掃描模塊,用于從當前掃描的單鏈表開始按前進指針的方向掃描,判斷待插入的目標元素與掃描點處的元素的大小關系,若掃描點處的元素與目標元素相等,則返回,結束本次單個元素的插入操作,繼續下一個元素的插入操作,若掃描點處的元素小于目標元素,則進入所述第二掃描模塊,若掃描點處的元素大于目標元素,則進入所述第三掃描模塊;
第二掃描模塊,用于在掃描點處的元素小于目標元素時,將計步器增加1,并判斷計步器中的計數值是否達到預設值,其中,預設值為概率因子p的倒數,若計步器的計數值達到預設值,則將掃描點處的節點高度增加1,即將該掃描點處的節點鏈接到掃描層的上面一層的鏈表中,同時計步器置0,掃描點向前移動,若計步器的計數值沒有達到預設值,則返回所述第一掃描模塊;
第三掃描模塊,用于在掃描點處的元素大于目標元素時,判斷當前掃描的層次是否為最底層,若是最底層,則返回掃描點的后退一個位置,并記為插入點,若不是最底層,則將掃描點后退一步,掃描層下移一層,從后退之后的掃描點處的節點開始,轉至所述第一掃描模塊;
元素插入模塊,用于在skiplist中不存在目標元素時,在最底層的有序單鏈表中將該目標元素插入到所述查詢模塊返回的插入點之后,且將節點高度設為1。
優選地,所述系統還包括:
初始化模塊,用于設置概率因子p和skiplist節點所能達到的高度閥值;分配skiplist對象,skiplist具有當前高度和頭結點兩個屬性,并初始化頭結點,以高度閥值作為頭節點的高度,分配前進鏈接指針數組,指針數組的每個元素指向空指針。
總體而言,通過本發明所構思的以上技術方案與現有技術相比,主要有以下的技術優點:
(1)本發明提供的這種基于多層鏈接分離的新的跳表構造方法,通過在查找過程中判斷計步器達到步長1/p來長高滿足條件的節點,實現skiplist的相鄰兩層節點數目比例為p,保證skiplist的隨機性數據結構的完整性;
(2)本發明所描述的跳表,其創建索引節點的操作被放在搜索過程中。需要注意的是,不限于插入操作所涉及的搜索。任何搜索過程都可以應用所提出的“檢查并創建索引節點”方法。
(3)相比隨機構造方案的查找過程,本發明提供的方案中,盡管新的skiplist的元素查找過程會在每層的掃描過程中增加單鏈表的鏈接操作,但是一次節點長高操作只涉及兩次指針的賦值操作,時間開銷為O(1),幾乎能忽略不計;然而,隨機構造方案的查找過程需要為插入節點保存查找路徑,即插入元素節點的前驅指針數組,而本發明提供的skiplist的查找過程卻無此特殊要求,只需返回底層單鏈表的插入點即可;
(4)相比隨機構造方案的插入開銷為skiplist的平均高度,即O(logn),n為skiplist中元素的個數,本發明提供的skiplist的插入過程僅涉及單鏈表特定插入點的插入操作,時間開銷為O(1);
(5)相比確定性構造方法,本發明提供的skiplist的構造方案在插入節點后,無需調整整個skiplist結構,從而節省重構skiplist操作的時間開銷。
附圖說明
圖1為skiplist數據結構示意圖;
圖2為本發明實施例公開的一種多層鏈接分離的skiplist構造方法的流程圖;
圖3為本發明實施例公開的一種單個元素查找過程的流程圖;
圖4(a)為本發明實施例公開的一種插入新元素之前的skiplist數據結構示意圖;
圖4(b)為本發明實施例公開的一種向skiplist中插入新元素的流程圖;
圖5為本發明實施例公開的一種多層鏈接分離的skiplist構造系統的結構示意圖。
具體實施方式
為了使本發明的目的、技術方案及優點更加清楚明白,以下結合附圖及實施例,對本發明進行進一步詳細說明。應當理解,此處所描述的具體實施例僅僅用以解釋本發明,并不用于限定本發明。此外,下面所描述的本發明各個實施方式中所涉及到的技術特征只要彼此之間未構成沖突就可以相互組合。
以下首先就本發明所涉及的技術術語進行解釋和說明:
如圖1所示,skiplist表示一種隨機化的數據結構,基于并聯的鏈表,其搜索的時間復雜度為O(log n),n為skiplist中元素的個數;跳表是對有序的鏈表以隨機高度的方式增加附加的前進鏈接,所以在列表中的查找可以快速的跳過部分列表。
如圖2所示為本發明實施例公開的一種多層鏈接分離的skiplist構造方法的流程圖,在圖2所示的方法中,包括以下步驟:
(1)單個元素的查詢,其子步驟為:
(1-1)設置當前掃描的層次為skiplist當前的最大高度,初始化計步器值為0,將當前所處的位置記為掃描點,將當前掃描的層次記為掃描層,將當前掃描的單鏈表記為掃描鏈;
(1-2)從當前掃描的單鏈表開始按前進指針的方向掃描,判斷待插入的目標元素與掃描點處的元素的大小關系,若掃描點處的元素與目標元素相等,則返回,結束本次單個元素的插入操作,繼續下一個元素的插入操作,若掃描點處的元素小于目標元素,則執行步驟(1-3),若掃描點處的元素大于目標元素,則執行步驟(1-4);
(1-3)計步器增加1,并判斷計步器中的計數值是否達到預設值,其中,預設值為概率因子p的倒數,若計步器的計數值達到預設值,則將掃描點處的節點高度增加1,即將該掃描點處的節點鏈接到掃描層的上面一層的鏈表中,同時計步器置0,掃描點向前移動,若計步器的計數值沒有達到預設值,則執行步驟(1-2);
(1-4)判斷當前掃描的層次是否為最底層,若是最底層,則返回掃描點的后退一個位置,并記為插入點,若不是最底層,則將掃描點后退一步,掃描層下移一層,從后退之后的掃描點處的節點開始,轉至執行步驟(1-2)。
參考圖3所示,為本發明實施例公開的一種單個元素查找過程的流程圖。通過圖3所示的查詢操作,單個元素的查詢操作過程將滿足預設值的節點長高,來滿足跳表節點概率因子為p的隨機性高度要求,完善跳表各層節點的概率比,提高后續元素的查找性能。
(2)單個元素插入:若skiplist中不存在目標元素,則在最底層的有序單鏈表中將該目標元素插入到步驟(1)返回的插入點之后,且將節點高度設為1。
通過上述單個元素的插入操作,單個元素的插入相比典型的skiplist插入操作,減少節點高度的隨機生成過程和該節點在多層有序單鏈表的鏈接過程,從而大大提高元素的插入性能。
優選地,在步驟(1)之前,還包括初始化操作:
設置概率因子p和skiplist節點所能達到的高度閥值;分配skiplist對象,skiplist具有當前高度和頭結點兩個屬性,并初始化頭結點,以高度閥值作為頭節點的高度,分配前進鏈接指針數組,指針數組的每個元素指向空指針。
為了便于對本發明提出的一種多層鏈接分離的skiplist構造方法的理解,以下結合實施例進一步闡述本發明提供的skiplist構造方法,在本實施例中,設置概率因子P為0.5,高度閾值為5,skiplist中含有元素1、4、5、7、11、13、17,依次向skiplist中插入14的流程如圖4所示,具體包括如下步驟:
(1)插入元素14的查找過程,包括如下子步驟:
(1.1)設置掃描層為skiplist當前的最大高度3,初始化計步器的值為0,從頭結點head開始順著前進方向進行掃描;
(1.2)首先,掃描點位于元素為4的節點處,14比4大,計步器增加1變為1,判斷計數器的值未達到1/p;
(1.3)掃描點順著前進方向移向下一個位置,即空指針NIL,后退一個位置,即回到元素為4的節點位置;
(1.4)判斷掃描層高度為3,未達到底層,故掃描層下移一層,位于第2層;
(1.5)掃描點順著前進方向移向下一個位置,即到達元素為7的位置,判斷14比7大,計步器增加1變為2,判斷計數器的值達到預設值1/p;
(1.6)長高元素為7的節點,同時將計步器置為0;
(1.7)掃描點順著前進方向移向下一個位置,即空指針NIL,后退一個位置,即回到元素為7的節點位置;
(1.8)判斷掃描層高度為2,未達到底層,故掃描層下移一層,位于第1層,即底層;
(1.9)同理,掃描點依次經過元素為11、13的節點,在元素為13的節點處,判斷計步器達到1/p,故長高元素為13的節點,計步器置為0;
(1.10)掃描點順著前進方向移向下一個位置,到達元素為17的位置,判斷17比14大,判斷掃描層已經到達底層,掃描點后退一步到達元素為13的節點處,返回掃描點的位置;
(2)插入元素14的過程包括如下子步驟:
在底層有序單鏈表中,將元素為14的節點插入到步驟(1)返回的位置后面;插入元素14過程結束。
圖5為本發明實施例公開的一種多層鏈接分離的skiplist構造系統的結構示意圖,在圖5所示的系統中包括:查詢模塊以及元素插入模塊;
上述查詢模塊包括:設置模塊、第一掃描模塊、第二掃描模塊以及第三掃描模塊:
上述設置模塊,用于設置當前掃描的層次為skiplist當前的最大高度,初始化計步器值為0,將當前所處的位置記為掃描點,將當前掃描的層次記為掃描層,將當前掃描的單鏈表記為掃描鏈;
上述第一掃描模塊,用于從當前掃描的單鏈表開始按前進指針的方向掃描,判斷待插入的目標元素與掃描點處的元素的大小關系,若掃描點處的元素與目標元素相等,則返回,結束本次單個元素的插入操作,繼續下一個元素的插入操作,若掃描點處的元素小于目標元素,則進入所述第二掃描模塊,若掃描點處的元素大于目標元素,則進入所述第三掃描模塊;
上述第二掃描模塊,用于在掃描點處的元素小于目標元素時,將計步器增加1,并判斷計步器中的計數值是否達到預設值,其中,預設值為概率因子p的倒數,若計步器的計數值達到預設值,則將掃描點處的節點高度增加1,即將該掃描點處的節點鏈接到掃描層的上面一層的鏈表中,同時計步器置0,掃描點向前移動,若計步器的計數值沒有達到預設值,則返回所述第一掃描模塊;
上述第三掃描模塊,用于在掃描點處的元素大于目標元素時,判斷當前掃描的層次是否為最底層,若是最底層,則返回掃描點的后退一個位置,并記為插入點,若不是最底層,則將掃描點后退一步,掃描層下移一層,從后退之后的掃描點處的節點開始,轉至所述第一掃描模塊;
上述元素插入模塊,用于在skiplist中不存在目標元素時,在最底層的有序單鏈表中將該目標元素插入到所述查詢模塊返回的插入點之后,且將節點高度設為1。
優選地,在圖5所示的系統中還包括:
初始化模塊,用于設置概率因子p和skiplist節點所能達到的高度閥值;分配skiplist對象,skiplist具有當前高度和頭結點兩個屬性,并初始化頭結點,以高度閥值作為頭節點的高度,分配前進鏈接指針數組,指針數組的每個元素指向空指針。
本領域的技術人員容易理解,以上所述僅為本發明的較佳實施例而已,并不用以限制本發明,凡在本發明的精神和原則之內所作的任何修改、等同替換和改進等,均應包含在本發明的保護范圍之內。