日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

SkipList 以及高度的确定

發布時間:2023/12/20 编程问答 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 SkipList 以及高度的确定 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

轉載:https://www.cnblogs.com/lnlvinso/p/8848883.html

? 結果:skiplist的高度是個隨機值。

SkipList理解

  記下自己對跳表SkipList的理解。

? ? ? ??SkipList采用空間換時間的思想,通過增加數據間的鏈接,達到加快查找速度的目的。

? ? ? ? 數據庫LevelDB和RocksDB中用到了SkipList,Redis中的有序set即zset也用到了SkipList。Java中也提供了ConcurrentSkipListMap,在并發量大的情況下,ConcurrentSkipListMap性能好。

? ? ? ? 先看SkipList的查找過程,引用網上的經典圖片,查找19。注意的是數據是有序的。

? ? ? ? ? 查找的過程從上至下,查找指針所經歷的位置順序如圖中的1,2,3,直到找到目標數據19。

? ? ? ? ? 再加一張圖,是怎么二分法查找的。

??

? ? ? ? ? ?

?   SkipList中創建新結點時,產生一個在1~MAX_LEVEL之間的隨機level值作為該結點的level。每個節點的高度是隨機的。

? ? ? ? ? ? MAX_LEVEL可以靜態指定,也可以動態增長。

? ? ? ? ? ? 關于MAX_LEVEL,覺得這篇文章的解釋是比較清楚的:https://blog.csdn.net/kisimple/article/details/38706729。下面是復制了部分的內容

? ? ? ? ? ??

   每個節點所能reach到的最遠的節點是隨機的,正如作者所說,SkipList使用的是概率平衡而不是強制平衡。

  O(logN)?

   既然是隨機算法,那怎么能保證O(logN)的復雜度?SkipList作者在論文中有給出了說明,這里從另一個角度說下我的理解。先定義一下,A node that has k forward pointers is called a level k node。假設k層節點的數量是k+1層節點的P倍,那么其實這個SkipList可以看成是一棵平衡的P叉樹,從最頂層開始查找某個節點需要的時間是O(logpN),which is O(logN) when p is a constant。

  下面看下Redis與LevelDB中實現SkipList所使用的隨機算法。

  Redis

  ? ?在t_zset.c中找到了redis使用的隨機算法。

?

/* Returns a random level for the new skiplist node we are going to create.* The return value of this function is between 1 and ZSKIPLIST_MAXLEVEL* (both inclusive), with a powerlaw-alike distribution where higher* levels are less likely to be returned. */ int zslRandomLevel(void) {int level = 1;while ((random()&0xFFFF) < (ZSKIPLIST_P * 0xFFFF))level += 1;return (level<ZSKIPLIST_MAXLEVEL) ? level : ZSKIPLIST_MAXLEVEL; }

?

    執行level += 1;的概率為ZSKIPLIST_P,也就是說k層節點的數量是k+1層節點的1/ZSKIPLIST_P倍。ZSKIPLIST_P(這個P是作者論文中的p)與ZSKIPLIST_MAXLEVEL在redis.h中定義,

#define ZSKIPLIST_MAXLEVEL 32 /* Should be enough for 2^32 elements */ #define ZSKIPLIST_P 0.25 /* Skiplist P = 1/4 */

    所以redis中的SkipList相當于是一棵四叉樹。

  LevelDB

    在skiplist.h中找到了LevelDB使用的隨機算法。

template<typename Key, class Comparator> int SkipList<Key,Comparator>::RandomHeight() {// Increase height with probability 1 in kBranchingstatic const unsigned int kBranching = 4;int height = 1;while (height < kMaxHeight && ((rnd_.Next() % kBranching) == 0)) {height++;}assert(height > 0);assert(height <= kMaxHeight);return height; }  (rnd_.Next() % kBranching) == 0)的概率為1/kBranching,所以LevelDB中的SkipList也是一棵四叉樹(kBranching = 4;不就是這個意思嗎^_^)。

? ? ? ? ? ? 總結:skiplist是有序的,采用類似二分法方式進行查找。查找、插入的平均時間復雜度是O(ln2)。

總結

以上是生活随笔為你收集整理的SkipList 以及高度的确定的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。