SkipList 跳表

為什么選擇跳表

目前經常使用的平衡數據結構有:B樹,紅黑樹,AVL樹,Splay Tree, Treep等。

?

想象一下,給你一張草稿紙,一只筆,一個編輯器,你能立即實現一顆紅黑樹,或者AVL樹

出來嗎? 很難吧,這需要時間,要考慮很多細節,要參考一堆算法與數據結構之類的樹,

還要參考網上的代碼,相當麻煩。

?

用跳表吧,跳表是一種隨機化的數據結構,目前開源軟件 Redis 和 LevelDB 都有用到它,

它的效率和紅黑樹以及 AVL 樹不相上下,但跳表的原理相當簡單,只要你能熟練操作鏈表,

就能輕松實現一個 SkipList。

?

有序表的搜索

考慮一個有序表:


?

從該有序表中搜索元素 < 23, 43, 59 > ,需要比較的次數分別為 < 2, 4, 6 >,總共比較的次數

為 2 + 4 + 6 = 12 次。有沒有優化的算法嗎? ?鏈表是有序的,但不能使用二分查找。類似二叉

搜索樹,我們把一些節點提取出來,作為索引。得到如下結構:



?這里我們把 < 14, 34, 50, 72 > 提取出來作為一級索引,這樣搜索的時候就可以減少比較次數了。

?我們還可以再從一級索引提取一些元素出來,作為二級索引,變成如下結構:

?

??

?

? ? ?這里元素不多,體現不出優勢,如果元素足夠多,這種索引結構就能體現出優勢來了。

?

跳表

下面的結構是就是跳表:

?其中 -1 表示 INT_MIN, 鏈表的最小值,1 表示 INT_MAX,鏈表的最大值。

?

?

跳表具有如下性質:

(1) 由很多層結構組成

(2) 每一層都是一個有序的鏈表

(3) 最底層(Level 1)的鏈表包含所有元素

(4) 如果一個元素出現在 Level i 的鏈表中,則它在 Level i 之下的鏈表也都會出現。

(5) 每個節點包含兩個指針,一個指向同一鏈表中的下一個元素,一個指向下面一層的元素。

?

跳表的搜索


?

例子:查找元素 117

(1) 比較 21, 比 21 大,往后面找

(2) 比較 37, ? 比 37大,比鏈表最大值小,從 37 的下面一層開始找

(3) 比較 71, ?比 71 大,比鏈表最大值小,從 71 的下面一層開始找

(4) 比較 85, 比 85 大,從后面找

(5) 比較 117, 等于 117, 找到了節點。

?

具體的搜索算法如下:?

?

C代碼??收藏代碼
  1. /*?如果存在?x,?返回?x?所在的節點,?
  2. ?*?否則返回?x?的后繼節點?*/??
  3. find(x)???
  4. {??
  5. ????p?=?top;??
  6. ????while?(1)?{??
  7. ????????while?(p->next->key?<?x)??
  8. ????????????p?=?p->next;??
  9. ????????if?(p->down?==?NULL)???
  10. ????????????return?p->next;??
  11. ????????p?=?p->down;??
  12. ????}??
  13. }??

?

?

跳表的插入

先確定該元素要占據的層數 K(采用丟硬幣的方式,這完全是隨機的)

然后在 Level 1 ... Level K 各個層的鏈表都插入元素。

例子:插入 119, K = 2


?

如果 K 大于鏈表的層數,則要添加新的層。

例子:插入 119, K = 4


?

丟硬幣決定 K

插入元素的時候,元素所占有的層數完全是隨機的,通過一下隨機算法產生:

?

C代碼??收藏代碼
  1. int?random_level()??
  2. {??
  3. ????K?=?1;??
  4. ??
  5. ????while?(random(0,1))??
  6. ????????K++;??
  7. ??
  8. ????return?K;??
  9. }??

?

相當與做一次丟硬幣的實驗,如果遇到正面,繼續丟,遇到反面,則停止,

用實驗中丟硬幣的次數 K 作為元素占有的層數。顯然隨機變量 K 滿足參數為 p = 1/2 的幾何分布,

K 的期望值 E[K] = 1/p = 2. 就是說,各個元素的層數,期望值是 2 層。

?

?

跳表的高度。

n 個元素的跳表,每個元素插入的時候都要做一次實驗,用來決定元素占據的層數 K,

跳表的高度等于這?n 次實驗中產生的最大 K,待續。。。

?

跳表的空間復雜度分析

根據上面的分析,每個元素的期望高度為 2, 一個大小為 n 的跳表,其節點數目的

期望值是 2n。

?

跳表的刪除

在各個層中找到包含 x 的節點,使用標準的 delete from list 方法刪除該節點。

例子:刪除 71


轉載于:https://www.cnblogs.com/papobabe/p/5885808.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/256356.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/256356.shtml
英文地址,請注明出處:http://en.pswp.cn/news/256356.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Redis failover過程

在Leader觸發failover之前&#xff0c;首先wait數秒(隨即0~5)&#xff0c;以便讓其他sentinel實例準備和調整。如果一切正常&#xff0c;那么leader就需要開始將一個salve提升為master&#xff0c;此slave必須為狀態良好(不能處于SDOWN/ODOWN狀態)且權重值最低(redis.conf中)的…

機器學習——深度學習之卷積神經網絡(CNN)——LeNet卷積神經網絡結構

目錄 一、卷積神經網絡 1、卷積神經的作用 2、LeNet 1&#xff09;數據庫準備——minst 2&#xff09;模型 二、關于卷積神經網絡結構的一些術語定義 1、特征圖&#xff08;Feature map&#xff09; 2、height&#xff08;長度&#xff09;、width&#xff08;寬度&…

工業相機(3D)主要參數詳述

一、前言 準確的完成相機選型是一個視覺工程師必備的技能&#xff0c;而選型前必須對其內部參數了如指掌。工業相機是一種比較復雜的產品&#xff0c;其參數很多&#xff0c;每個參數可能會有不同的標準&#xff0c;下面對主要的參數會做比較詳細的闡述。 二、參數詳述 2.1 …

JAVA8永久代

在Java虛擬機&#xff08;以下簡稱JVM&#xff09;中&#xff0c;類包含其對應的元數據&#xff0c;比如類的層級信息&#xff0c;方法數據和方法信息&#xff08;如字節碼&#xff0c;棧和變量大小&#xff09;&#xff0c;運行時常量池&#xff0c;已確定的符號引用和虛方法表…

Struts 2初體驗

Struts2簡介&#xff1a; Struts2是一個基于MVC設計模式的Web應用框架&#xff0c;它本質上相當于一個servlet&#xff0c;在MVC設計模式中&#xff0c;Struts2作為控制器(Controller)來建立模型與視圖的數據交互。 Struts 2 目錄結構:     apps目錄&#xff1a;Struts2示例…

機器學習——深度學習之數據庫和自編碼器

目錄 一、數據庫——數據獲取 1、Mnist 2、ImageNet 二、自編碼器&#xff08;Auto-encoder&#xff09;——參數初始化 1、功能 2、基本思想 1&#xff09;訓練第一層 2&#xff09;訓練第二層及以后的神經網絡 ? 3&#xff09;利用BP對整個神經網絡的參數初始值進…

Halcon例程詳解 (深度圖轉換為3D圖像)—— xyz_attrib_to_object_model_3d

一、前言 深度圖向點云圖進行轉換是進行3D檢測項目時會遇到的問題&#xff0c;halcon里也有針對此問題的相關例程&#xff0c;下面對此例程進行分析。通過學習此例程&#xff0c;我們可以掌握如何將一張深度圖像和一張正常二維圖像轉換為3D點云。 二、分析 * 初始化界面 dev…

動態代理之Cglib淺析

什么是Cglib Cglib是一個強大的&#xff0c;高性能&#xff0c;高質量的代碼生成類庫。它可以在運行期擴展JAVA類與實現JAVA接口。其底層實現是通過ASM字節碼處理框架來轉換字節碼并生成新的類。大部分功能實際上是ASM所提供的&#xff0c;Cglib只是封裝了ASM&#xff0c;簡化了…

機器學習——深度學習之卷積神經網絡(CNN)——AlexNet卷積神經網絡結構

目錄 一、AlexNet卷積神經網絡結構模型 1、數據庫ImageNet 2、AlexNet第一層卷積層 二、AlexNet卷積神經網絡的改進 1、非線性變化函數的改變——ReLU 2、最大池化&#xff08;Max Pooling&#xff09;概念的提出——卷積神經網絡通用 1&#xff09;池化層 2&#xff0…

POJ - 3470 Walls

小鳥往四個方向飛都枚舉一下&#xff0c;數據范圍沒給&#xff0c;離散以后按在其中一個軸線排序&#xff0c;在線段樹上更新墻的id&#xff0c;然后就是點查詢在在哪個墻上了。 這題有個trick&#xff0c;因為數據范圍沒給我老以為是inf設置小了&#xff0c;WA了很多發。&…

C# —— 深入理解委托類型

一. 委托定義 1. 委托與多播委托 委托類型表示對具有特定參數列表和返回類型的方法的引用&#xff0c;定義了委托實例可以調用的某類方法。 通過委托&#xff0c;我們可以動態的通過委托變量來調用委托方法。一般用delegate來命名委托類型,但Action和Func也可以達到同樣的效果…

【VS開發】【C++語言】reshuffle的容器實現算法random_shuffle()的使用

假設你需要指定范圍內的隨機數&#xff0c;傳統的方法是使用ANSI C的函數random(),然后格式化結果以便結果是落在指定的范圍內。但是&#xff0c;使用這個方法至少有兩個缺點。首先&#xff0c;做格式化時&#xff0c;結果常常是扭曲的&#xff0c;所以得不到正確的隨機數&…

C#委托——基礎2

在上一篇隨筆中&#xff0c;簡要說明了怎樣定義委托&#xff0c;定義事件&#xff0c;訂閱事件&#xff0c;最后也實現了效果&#xff0c;就是當員工類的某個對象&#xff0c;執行某個事件時&#xff0c;委托事件被觸發&#xff0c;后面也得到了結果&#xff0c;但是想象一下實…

機器學習——深度學習之編程工具、流行網絡結構、卷積神經網絡結構的應用

目錄 一、編程工具 caffe實現LENET-5 二、流行的網絡結構 1、VGGNET 2、Googlenet ? 3、ResNet? ? 三、卷積神經網絡的應用 1、人臉識別 ? 2、人臉驗證 3、人臉特征點檢測 4、卷積神經網絡壓縮 一、編程工具 caffe的優點&#xff1a;模型標準化&#xff0c;源代碼…

Halcon例程詳解(激光三角系統標定)—— calibrate_sheet_of_light_calplate.hdev

前言 1 激光三角測距 激光三角測距法原理很簡單,是通過一束激光以一定的入射角度照射被測目標,激光在目標表面會產生漫反射,在另一角度利用透鏡對反射激光匯聚成像,光斑成像在CCD(Charge-coupled Device,感光耦合組件)位置傳感器上。當被測物體沿激光方向發生移動時,…

【轉】如何實現一個文件系統

如何實現一個文件系統 摘要 本章目的是分析在Linux系統中如何實現新的文件系統。在介紹文件系統具體實現前先介紹文件系統的概念和作用&#xff0c;抽象出文件系統概念模型。熟悉文件系統的內涵后&#xff0c;我們再進一步討論Linux系統中文件系統的特殊風格和具體文件系統在Li…

【tenserflow】——數據類型以及常用屬性

目錄 一、什么是Tensor&#xff1f; 二、Tensorflow常見數據類型 三、Tensorflow常見屬性device\cpu\gpu\ndim\shape\rank等 1、創建一個tensor 1&#xff09;tf.constant() 2)tf.Variable() 2、判斷一個變量是否為tensor張量 3、生成不同設備&#xff08;cpu,gpu&#x…

C# 事件詳解附實例分析

一、定義 事件是兩個對象間發布消息和響應后處理消息的過程&#xff0c;通過委托類型來實現的。 事件的機制被稱為發布-訂閱機制&#xff0c;其算法過程為&#xff1a;首先定義一個委托類型&#xff0c;然后在發布者類中聲明一個event事件&#xff0c;同時此類中還有一個用來觸…

網頁開發瀏覽器兼容性問題

1、在ie6下的雙margin問題 在ie6下&#xff0c;設置了float的元素&#xff0c;以float:left為例&#xff0c;如圖所示。會出現第一個浮動元素&#xff0c;即相對于父級元素浮動的&#xff0c;會出現雙倍margin的問題。 注意僅僅是相對于父級元素浮動的&#xff0c;即第一個會出…

【tensorflow】——創建tensor的方法

目錄 1、tf.constant() 2、tf.Variable() 3、tf.zeros():用0去填充指定形狀的數組 4、tf.convert_to_tensor(a,dtypetf.int32) 5、tf.ones():用1去填充指定形狀的數組 6、tf.fill():用指定的元素去填充指定形狀的數組 7、隨機化初始化進行創建 1&#xff09;normal正態分…