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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

跳跃表(Skip list)原理与java实现

發布時間:2023/12/3 编程问答 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 跳跃表(Skip list)原理与java实现 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

轉載自?【算法導論33】跳躍表(Skip list)原理與java實現

Skip list是一個用于有序元素序列快速搜索的數據結構,由美國計算機科學家William Pugh發明于1989年。它的效率和紅黑樹以及 AVL 樹不相上下,但實現起來比較容易。作者William Pugh是這樣介紹Skip list的:?
Skip lists are a probabilistic data structure that seem likely to supplant balanced trees as the implementation method of choice for many applications. Skip list algorithms have the same asymptotic expected time bounds as balanced trees and are simpler, faster and use less space.?
Skip list是一個“概率型”的數據結構,可以在很多應用場景中替代平衡樹。Skip list算法與平衡樹相比,有相似的漸進期望時間邊界,但是它更簡單,更快,使用更少的空間。?
Skip list是一個分層結構多級鏈表,最下層是原始的鏈表,每個層級都是下一個層級的“高速跑道”。?
?
跳躍的表的性質包括:?
某個i層的元素,出現在i+1層的概率p是固定的,例如常取p=1/2或p=1/4;?
平均來講,每個元素出現在1/(1-p)個鏈表中;?
最高的元素,例如head通常采用Int.MIN_VALUE作為的最小值,會出現在每一層鏈表中;?
原始的鏈表元素如果是n,則鏈表最多層。例如,p=1/2時,層數為。?
跳躍表的空間復雜度為O(n),插入刪除的時間復雜度是。例如,p=1/2時,復雜度為。

相關資料

Skip list的維基百科;?
《算法導論》網易公開課Skip list。

跳躍表的構建

這里描述一下網易公開課《算法導論》“跳躍表”這一節的內容。?
空的跳躍表頭尾相連的雙向鏈表。


向鏈表中放入key-value,假如key是1。?

此時,不斷投擲硬幣,如果是反面,則不提升該節點,停止投擲硬幣;否則不斷提升該節點,并且垂直方向進行節點連接。?

如果上一步沒有提升,再插入key-value,key等于2,然后不斷投擲硬幣,發現是投了一次正面,需要提升一次。但第二次投的是反面,不再提升。?

再插入key-value,key等于3,然后不斷投擲硬幣,發現第一次就投了反面,不提升。?

這樣的規則一直持續下去。由于連續投正面的概率是0.5,0.5*0.5……,所以某一個節點提升很多層的概率是很低的。這也是為什么說跳躍表是一種概率型數據結構的來源。?
跳躍表的查詢也比較簡單。例如要查找key是3的節點,則從最上層開始查找,直到找到大于或等于3的位置,然后返回上一個節點,再往下一層繼續向右尋找。例如三層的跳躍表查詢路徑如下。?

這樣,就跳過了很多節點,所以叫做“跳躍表”。

Java實現

這里參考了“跳躍表(Skip List)-實現(Java)”,將其更改為模版形式,并多處進行了重構。?

節點類

/*** 跳躍表的節點,包括key-value和上下左右4個指針* created by 曹艷豐,2016-08-14* 參考:http://www.acmerblog.com/skip-list-impl-java-5773.html* */ public class SkipListNode <T>{public int key;public T value;public SkipListNode<T> up, down, left, right; // 上下左右 四個指針public static final int HEAD_KEY = Integer.MIN_VALUE; // 負無窮public static final int TAIL_KEY = Integer.MAX_VALUE; // 正無窮public SkipListNode(int k,T v) {// TODO Auto-generated constructor stubkey = k;value = v;}public int getKey() {return key;}public void setKey(int key) {this.key = key;}public T getValue() {return value;}public void setValue(T value) {this.value = value;}public boolean equals(Object o) {if (this==o) {return true;}if (o==null) {return false;}if (!(o instanceof SkipListNode<?>)) {return false;}SkipListNode<T> ent;try {ent = (SkipListNode<T>) o; // 檢測類型} catch (ClassCastException ex) {return false;}return (ent.getKey() == key) && (ent.getValue() == value);}@Overridepublic String toString() {// TODO Auto-generated method stubreturn "key-value:"+key+"-"+value;} }

跳躍表實現。

import java.util.Random;/*** 不固定層級的跳躍表* created by 曹艷豐,2016-08-14* 參考:http://www.acmerblog.com/skip-list-impl-java-5773.html* */ public class SkipList <T>{private SkipListNode<T> head,tail;private int nodes;//節點總數private int listLevel;//層數private Random random;// 用于投擲硬幣private static final double PROBABILITY=0.5;//向上提升一個的概率public SkipList() {// TODO Auto-generated constructor stubrandom=new Random();clear();}/***清空跳躍表* */public void clear(){head=new SkipListNode<T>(SkipListNode.HEAD_KEY, null);tail=new SkipListNode<T>(SkipListNode.TAIL_KEY, null);horizontalLink(head, tail);listLevel=0;nodes=0;}public boolean isEmpty(){return nodes==0;}public int size() {return nodes;}/*** 在最下面一層,找到要插入的位置前面的那個key* */private SkipListNode<T> findNode(int key){SkipListNode<T> p=head;while(true){while (p.right.key!=SkipListNode.TAIL_KEY&&p.right.key<=key) {p=p.right;}if (p.down!=null) {p=p.down;}else {break;}}return p;}/*** 查找是否存儲key,存在則返回該節點,否則返回null* */public SkipListNode<T> search(int key){SkipListNode<T> p=findNode(key);if (key==p.getKey()) {return p;}else {return null;}}/*** 向跳躍表中添加key-value* * */public void put(int k,T v){SkipListNode<T> p=findNode(k);//如果key值相同,替換原來的vaule即可結束if (k==p.getKey()) {p.value=v;return;}SkipListNode<T> q=new SkipListNode<T>(k, v);backLink(p, q);int currentLevel=0;//當前所在的層級是0//拋硬幣while (random.nextDouble()<PROBABILITY) {//如果超出了高度,需要重新建一個頂層if (currentLevel>=listLevel) {listLevel++;SkipListNode<T> p1=new SkipListNode<T>(SkipListNode.HEAD_KEY, null);SkipListNode<T> p2=new SkipListNode<T>(SkipListNode.TAIL_KEY, null);horizontalLink(p1, p2);vertiacallLink(p1, head);vertiacallLink(p2, tail);head=p1;tail=p2;}//將p移動到上一層while (p.up==null) {p=p.left;}p=p.up;SkipListNode<T> e=new SkipListNode<T>(k, null);//只保存key就okbackLink(p, e);//將e插入到p的后面vertiacallLink(e, q);//將e和q上下連接q=e;currentLevel++;}nodes++;//層數遞增}//node1后面插入node2private void backLink(SkipListNode<T> node1,SkipListNode<T> node2){node2.left=node1;node2.right=node1.right;node1.right.left=node2;node1.right=node2;}/*** 水平雙向連接* */private void horizontalLink(SkipListNode<T> node1,SkipListNode<T> node2){node1.right=node2;node2.left=node1;}/*** 垂直雙向連接* */private void vertiacallLink(SkipListNode<T> node1,SkipListNode<T> node2){node1.down=node2;node2.up=node1;}/*** 打印出原始數據* */@Overridepublic String toString() {// TODO Auto-generated method stubif (isEmpty()) {return "跳躍表為空!";}StringBuilder builder=new StringBuilder();SkipListNode<T> p=head;while (p.down!=null) {p=p.down;}while (p.left!=null) {p=p.left;}if (p.right!=null) {p=p.right;}while (p.right!=null) {builder.append(p);builder.append("\n");p=p.right;}return builder.toString();}}

下面進行一下測試。

public class Main {public static void main(String[] args) {// TODO Auto-generated method stubSkipList<String> list=new SkipList<String>();System.out.println(list);list.put(2, "yan");list.put(1, "co");list.put(3, "feng");list.put(1, "cao");//測試同一個key值list.put(4, "曹");list.put(6, "豐");list.put(5, "艷");System.out.println(list);System.out.println(list.size());} }

Java中的跳躍表

Java API中提供了支持并發操作的跳躍表ConcurrentSkipListSet和ConcurrentSkipListMap。下面摘錄”Java多線程(四)之ConcurrentSkipListMap深入分析“中的一些結論。?
有序的情況下:?
? 在非多線程的情況下,應當盡量使用TreeMap(紅黑樹實現)。?
? 對于并發性相對較低的并行程序可以使用Collections.synchronizedSortedMap將TreeMap進行包裝,也可以提供較好的效率。但是對于高并發程序,應當使用ConcurrentSkipListMap。?
無序情況下:?
? 并發程度低,數據量大時,ConcurrentHashMap 存取遠大于ConcurrentSkipListMap。?
? 數據量一定,并發程度高時,ConcurrentSkipListMap比ConcurrentHashMap效率更高。


總結

以上是生活随笔為你收集整理的跳跃表(Skip list)原理与java实现的全部內容,希望文章能夠幫你解決所遇到的問題。

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

主站蜘蛛池模板: 黄色在线免费看 | 欧美性猛交aaaa片黑人 | 欧美三级三级三级爽爽爽 | 女人脱裤子让男人捅 | 欧美成人国产va精品日本一级 | 国产冒白浆 | 国产黑丝在线视频 | 波多野结衣中文字幕在线播放 | 国产在线国偷精品免费看 | 国产交换配乱淫视频免费 | 国产高h视频 | 波多野结衣免费看 | 国产av无码专区亚洲a∨毛片 | 色偷偷91 | 久久免费看少妇 | 国产女人18毛片18精品 | 三级黄色片网站 | 一区二区三区午夜 | 香蕉钻洞视频 | 999国产在线| 久久久精品免费视频 | 国产男女猛烈无遮挡免费视频 | 99re6在线精品视频免费播放 | 在线视频免费播放 | 天天爽网站 | 制服诱惑一区二区 | 秋霞自拍 | 玩弄白嫩少妇xxxxx性 | 三级在线视频 | 成年人免费在线看 | 国产一二在线 | 亚洲狼人社区 | 欧美另类69 | 午夜福利三级理论电影 | 正在播放欧美 | 中文字幕有码av | 国产三级大片 | 国产精品一亚洲av日韩av欧 | 超碰人人91 | 精品视频一区二区三区四区 | 91小视频在线 | 成人黄色在线网站 | 亚洲女同av | 亚洲免费色视频 | 亚洲电影一区二区 | 中日韩在线播放 | 日韩精品福利 | 久久精品激情 | 欧美视频一区 | 国产美女黄网站 | 国产h自拍| 久久99网| 森泽佳奈作品在线观看 | 无码少妇一区二区三区 | 波多野结衣视频免费观看 | 亚洲精品1234 | 欧美老女人性生活视频 | 欧美精品免费一区二区三区 | a猛片 | 一本久草 | 精品国内自产拍在线观看视频 | 国内毛片毛片毛片 | 日本一区二区免费视频 | 日本少妇激情舌吻 | 国产精品久久影院 | 色女人网 | 国产极品一区二区 | 完美搭档在线观看 | 米奇影音| 少妇毛片视频 | 丰满少妇一区二区三区专区 | 色777| 国产理论视频在线观看 | 欧美日韩国产专区 | 欧美福利视频导航 | 黄色片xxx | 97操操 | 扒下小娇妻的内裤打屁股 | 日本在线视频免费观看 | 免费观看黄色网 | 亚洲 欧美 激情 另类 校园 | 久草影视在线 | av作品在线观看 | 秋霞成人网 | 女人扒开腿免费视频app | 综合激情久久 | 国产盗摄精品一区二区酒店 | 91超碰在线 | 另类av小说 | 九月色婷婷 | 我们好看的2018视频在线观看 | 色呦呦视频在线观看 | 毛片大全在线观看 | 麻豆视频成人 | 亚洲欧美日韩第一页 | 国产又粗又黄又爽 | 日韩成人在线免费视频 | 欧美区视频 | wwwxx日本 |