探索Skip List 跳躍表

2022-05-16 02:25:14 字數 1401 閱讀 5068

附william pugh的** skip lists: a probabilistic alternative to balanced trees

以下內容針對的是skip list的插入和刪除,建議你先到其他地方大概了解一下skip list長什麼樣子的,然後再過來看看這篇,最好還是看一眼**先,部分挺容易看懂的。redis中的sorted set基本就是使用skip list,只是稍作修改。

skip list 是一種資料結構,實質上為乙個鍊錶,專門用於儲存有序元素,提供的查詢速度可與平衡二叉樹媲美,優點是實現簡單。

**中skip list就是長上面這樣的,每個節點有多個forward指標,指向在其後面的元素。將forward指標分層,稱為level,level為1的那層就是單純的有序單鏈表,隨著層次遞增,元素會越來越少。比如level的取值範圍可以是[1, 32]

先快速看一眼下面翻譯過來的偽碼實現。

void insert(list, searchkey, newvalue)

x = x->forward[1]; // 這在最低層

if(x->key == searchkey)

else

x = createnode(v, searchkey, newvalue);

for(i = 1 to lv) // 調整相關指標}}

實現原理是,用乙個update陣列儲存"最大且小於searchkey的元素",用它來調整涉及到的指標指向。搜尋時從高層往低層搜尋,順便記錄update陣列,調整指標時從低層往高層調整。可能出現的情況是,新節點的level大於原來list的最大level,此時需要更新一下list的最大level。

randomlevel()比較容易實現,就是拋硬幣法,有概率性,越高的level出現頻率越低,因為不能直接一下子就返回過大的數字。返回乙個數字n表示拋了n+1次才出現反面,但要求n<=maxlevel。這種取level的方式很巧妙。

void delete(list, searchkey)

x = x->forward[i];

if(x->key == searchkey) // 若命中,則刪

free(x);

// 可能需要更新list的max level

while(list->level > 1 && !list->header->forward[list->level])

list->level = list->level - 1;}}

看過insert之後,這個不用解釋也能看懂了。

跳躍表skiplist簡析

1.簡述 跳躍表 skiplist 最初由 william pugh發表在acm通訊上的 skip lists a probabilistic alternative to balanced trees 中,作者給出的定義是 跳表是在很多應用中有可能替代平衡樹而作為實現方法的一種資料結構。跳躍列表的...

Redis學習 4 跳躍表(skiplist)

跳躍表 skiplist 是一種有序的資料結構,它通過在每個節點中維持多個指向其他節點的指標,從而達到快速訪問節點的目的。它的效率可以媲美平衡樹,跳躍表的平均複雜度o logn 最壞情況複雜度o n 並且其原理和 都要比平衡樹更加簡單,因此很多地方多用跳躍表代替平衡樹。1,redis使用跳躍表作為有...

Redis資料結構 skiplist(跳躍表)

跳躍表在redis中主要用於有序集合鍵的實現,其他地方沒怎麼用到,但是這種資料結構在面試的時候經常會問到,因為它作為一種查詢時間複雜度為o logn 的特殊的鍊錶,效率堪比紅黑樹或平衡樹,而實現難度卻遠小於它們。下面分3個模組講解redis的跳躍表實現 一 跳躍表的應用場景 在redis中,當有序集...