Implementing the skip list data structure in java --reference
reference:http://www.mathcs.emory.edu/~cheung/Courses/323/Syllabus/Map/skip-list-impl.html
- The link list element structure used to implement a Skip List
- The link list element used to implement the skip list has 4 links (not including the data portion):

- The link list element used to implement the skip list has 4 links (not including the data portion):
- The Entry strcuture in a Skip List (the SkipListEntry class)
- Skip List entry:
public class SkipListEntry
{
public String key;
public Integer value; public SkipListEntry up; // up link
public SkipListEntry down; // down link
public SkipListEntry left; // left link
public SkipListEntry right; // right link ...
(methods)
}
Note:
- As you can see, my entry type is again very specific (no generic types):
- String key
- Integer value
- When I write the demo program, I will do it using specific types (classes), not parameterized classes
I have showed you how to convert a specific class into a parameterized class, so you can write one if you want to
- Reason for using specific classes:
- My choice is didactic in nature; I don't want to spend time analyzing the overly complex syntax of parameterized classes
- I want to spend my time teaching algorithms, not Java syntax
- As you can see, my entry type is again very specific (no generic types):
- Skip List entry:
- Making (and using) the special −∞ and +∞ elements
- Representing the −∞ element and the +∞ element:
- The −∞ and the +∞ is just an ordinary Skip List Entry containing a special value for the key field.
- We can accommodate the −∞ element and the +∞ element by defining 2 special key value:
public class SkipListEntry
{
public String key;
public Integer value; public SkipListEntry up, down, left, right; public static String negInf = "-oo"; // -inf key value
public static String posInf = "+oo"; // +inf key value ....
} - How to instantiate a Skip List entry containing +∞:
SkipListEntry x = new SkipListEntry( SkipListEntry.posInf, null );
How to check if an Skip List entry x contains +∞:
key == SkipListEntry.posInf
OK, now we move on to the Skip list itself....
- Representing the −∞ element and the +∞ element:
- Structure (class) to represent a Skip List
- Remember that a Skip List is a very complicated list
But.... It is never the less a list
- To represent a list, we only use a pointer (that points to the first element)
- Often, we use more pointers for improve efficiency (such as a tail pointer)
- Variables in the SkipList class:
public class SkipList
{
public SkipListEntry head; // First element of the top level
public SkipListEntry tail; // Last element of the top level public int n; // number of entries in the Skip List public int h; // Height
public Random r; // Coin toss .... }Note:
- The Random object r is used to determine the height of a newly added entry
(We use r to simulate a coin toss experiment)
- The Random object r is used to determine the height of a newly added entry
- Example illustrating how the variables are used:

Note:
- Since the logical top level does not contain any entries:
- The implementation will omit the logical top layer
- The variables head and tail provide quick access to the end elements of the real top layer
Usage of head and tail:
- They allow us to easily add an new layer above the top layer
- Since the logical top level does not contain any entries:
- Remember that a Skip List is a very complicated list
- Constructing a Skip List object
- The constructor will construct an empty Skip List which looks like this:

- Constructor code:
public SkipList() // Constructor...
{
SkipListEntry p1, p2; /* -----------------------------------
Create an -oo and an +oo object
----------------------------------- */
p1 = new SkipListEntry(SkipListEntry.negInf, null);
p2 = new SkipListEntry(SkipListEntry.posInf, null); /* --------------------------------------
Link the -oo and +oo object together
--------------------------------------- */
p1.right = p2;
p2.left = p1; /* --------------------------------------
Initialize "head" and "tail"
--------------------------------------- */
head = p1;
tail = p2; /* --------------------------------------
Other initializations
--------------------------------------- */
n = 0; // No entries in Skip List
h = 0; // Height is 0 r = new Random(); // Make random object to simulate coin toss
} - The SkipList class so far:
public class SkipList
{
public SkipListEntry head; // First element of the top level
public SkipListEntry tail; // Last element of the top level public int n; // number of entries in the Skip List public int h; // Height
public Random r; // Coin toss public SkipList() // Constructor...
{
SkipListEntry p1, p2; p1 = new SkipListEntry(SkipListEntry.negInf, null);
p2 = new SkipListEntry(SkipListEntry.posInf, null); head = p1;
tail = p2; p1.right = p2;
p2.left = p1; n = 0; h = 0;
r = new Random();
} ...
}
- The constructor will construct an empty Skip List which looks like this:
- Implementing the basic Map operations
- Basic Map operations:
- get()
- put()
- remove()
Notice that each basic operation must first find (search) the appropriate entry (using a key) before the operation can be completed.
So we must learn how to search a Skip List for a given key first....
- Basic Map operations:
- Search operation in a skip list
- Consider the links traversed to locate the key 50:

- Psuedo code:
p = head; repeat
{ Move to the right until your right neighbor node
contains a key that is greater than k if ( not lowest level )
Drop down one level
else
exit
} - Search algorithm for Skip List:
/* ------------------------------------------------------
findEntry(k): find the largest key x <= k
on the LOWEST level of the Skip List
------------------------------------------------------ */ public SkipListEntry findEntry(String k)
{
SkipListEntry p; /* -----------------
Start at "head"
----------------- */
p = head; while ( true )
{
/* ------------------------------------------------
Search RIGHT until you find a LARGER entry E.g.: k = 34 10 ---> 20 ---> 30 ---> 40
^
|
p must stop here
p.right.key = 40
------------------------------------------------ */
while ( (p.right.key) != SkipListEntry.posInf &&
(p.right.key).compareTo(k) <= 0 )
{
p = p.right; // Move to right
} /* ---------------------------------
Go down one level if you can...
--------------------------------- */
if ( p.down != null )
{
p = p.down; // Go downwards
}
else
{
break; // We reached the LOWEST level... Exit...
}
} return(p); // Note: p.key <= k
} - Note:
- If the key k is found in the Skip List, findEntry(k) will return the reference to the entry containg the key k
- If the key k is not found in the Skip List, findEntry(k) will return the reference to the floorEntry(k) entry containg a key that issmaller than k
Example: findEntry(42) will return the reference to 39:

- If the key k is found in the Skip List, findEntry(k) will return the reference to the entry containg the key k
- Consider the links traversed to locate the key 50:
- Implementing the "get(Key k)" method
- get(k):
/** Returns the value associated with a key. */ public Integer get (String k)
{
SkipListEntry p; p = findEntry(k); if ( k.equals( p.key ) )
return(p.value);
else
return(null);
}
- get(k):
- Put(k,v): inserting into a Skip List
- Pseudo code for put(k,v):
put(k, v)
{
SkipListEntry p; p = findEntry(k); if ( k.equals( p.key ) ) // Found !
{
p.value = v; // Update the value
return; // Done
} /* ==================================================
Not found. Then: p == floorEntry(k) !!!
================================================== */ (1) insert (k,v) AFTER p
(2) make a column of (k,v) of RANDOM height
}
- Recall what happens when we insert a new entry:
- Before insertion:

- After inserting key 42:

Note:
- As part of the insert operation, we will make a column (see figure above) for that key
- The height of the column will be random...
(We have also seen how to use a random "trial" to generate a random height)
- As part of the insert operation, we will make a column (see figure above) for that key
- Before insertion:
- Step-by-step depictions of the steps necessary for insertion: put("42", ??)
- Before the insertion:

- Step 1: find the insert position
p = findEntry(k)

- Step 2: insert q after p:

- Now make a column of random height: repeat these steps a random number of times
- Starting at p, (using p to) scan left and find the first entry that has an up-entry:

Make p point to the up-element:

- Create a new entry with the same key (we are making the "tower"):

- Insert the newly created entry: right of p and up from q:

- Make q point to the newly inserted entry (to continue the iteration if necessay)

- Starting at p, (using p to) scan left and find the first entry that has an up-entry:
- I will repeat the steps and show the effect of building a "tower":
- Starting at p, scan left and find the first entry that has an up-element:

- Create a new entry (we are making another level of the "tower"):

- Insert the newly created entry: right of p and up from q:

- Make q point to the newly inserted entry (to continue the iteration if necessay)

(And so on)
- Starting at p, scan left and find the first entry that has an up-element:
- Before the insertion:
- Note:
- If the height of the "tower" is = h:

we must add an new empty layer before we can insert another entry:

- If the height of the "tower" is = h:
- Pseudo code for put(k,v):
- Adding a (empty) layer
- Before we can do anything, We need to what are the changes in the Skip List when we add an empty layer to the Skip List:
- Here is the Skip List before we add a new (empty) top layer:

- Here is the Skip List before we add a new (empty) top layer:

- Here is the Skip List before we add a new (empty) top layer:
- Add layer algorithm:
SkipListEntry p1, p2; /* -----------------------------
Make the -oo and +oo entries
---------------------------- */
p1 = new SkipListEntry(SkipListEntry.negInf, null);
p2 = new SkipListEntry(SkipListEntry.posInf, null); /* --------------------
Link them
-------------------- */
p1.right = p2;
p1.down = head; p2.left = p1;
p2.down = tail; head.up = p1;
tail.up = p2; /* --------------------
Update head and tail
-------------------- */
head = p1;
tail = p2; h = h + 1; // One more level...
- Before we can do anything, We need to what are the changes in the Skip List when we add an empty layer to the Skip List:
- The put() method
- put(k,v) psuedo code:
p = findEntry(k); // Find insert location if ( entry found )
{
update the value in p;
exit;
} /* ----------------------------------
Insert a brand new entry (k,v) p put q here
| |
V V
[ ] <------> [ ]
---------------------------------- */ q = new Entry(k,v); // Make new entry
link q after p; /* ------------------------
Make a random tower...
------------------------ */
while ( random() < 0.5 /* coin toss */ )
{
if ( height of tower >= h )
{
create a new TOP layer (see: click here)
} p = Find the first left element in the next level above; q = new Entry(k,v);
link q after p;
}
- The put() method for Skip List in Java:
public Integer put (String k, Integer v)
{
SkipListEntry p, q;
int i; p = findEntry(k); // Try find the entry /* ------------------------
Check if key is found
------------------------ */
if ( k.equals(p.key) ) // If key found, update the value and we are done...
{
Integer old = p.value; // Remember the old value p.value = v; // Update value return(old); // Return the old value
} /* -------------------------------------------------------------
Key k is not found, then p = floorEntry(k) (See: click here) The rest of the code will insert a new entry (k,v)
------------------------------------------------------------- */ q = new SkipListEntry(k,v); // Create a new entry with k and v /* --------------------------------------------------------------
Insert q into the lowest level after SkipListEntry p: p put q here p q
| | | |
V V V V V
Lower level: [ ] <------> [ ] ==> [ ] <--> [ ] <--> [ ]
--------------------------------------------------------------- */
q.left = p;
q.right = p.right;
p.right.left = q;
p.right = q; /* -----------------------------------------------------
Make a "tower" of the entry e or RANDOM height
----------------------------------------------------- */ i = 0; // Current level = 0 while ( r.nextDouble() < 0.5 /* Coin toss */ )
{
// Coin toss success ! ---> build one more level !!! /* -------------------------------------------------------------------
Check if we need to increase the height of the -oo and +oo "pillars
------------------------------------------------------------------- */
if ( i >= h ) // We reached the top level !!!
{
Create a new empty TOP layer (see: click here)
(Put the code from above here.... I left it out for brevity)
} /* ------------------------------------
Find first element with an UP-link
------------------------------------ */
while ( p.up == null )
{
p = p.left;
} /* --------------------------------
Make p point to this UP element
-------------------------------- */
p = p.up; /* ---------------------------------------------------
Add one more (k,*) to the column Schema for making the linkage: p <--> e(k,*) <--> p.right
^
|
v
q
---------------------------------------------------- */
SkipListEntry e; e = new SkipListEntry(k, null); // Don't need the value... /* ---------------------------------------
Initialize links of e
--------------------------------------- */
e.left = p;
e.right = p.right;
e.down = q; /* ---------------------------------------
Change the neighboring links..
--------------------------------------- */
p.right.left = e;
p.right = e;
q.up = e; q = e; // Set q up for next iteration (if there is one)
// See here for more detail: click here i = i + 1; // Current level increases by one
} n = n + 1; // One more entry in the Skip List return(null); // No old value
}
- Example Program: (Demo above code)
- SkipListEntry.java Prog file: click here
- SkipList.java Prog file: click here
- Test program 1 (inserts 4 entries): click here
- Test program 2 (inserts 40 entries): click here
Example output: (The keys are strings)
- - - - - - - - - -
10
13
15 15
2
21
25
31 31 31
33 33 33 33 33 33 33 33 33 33
36
38
39 39 39 39 39
41 41 41
42 42 42 42
5 5 5
54 54
57
59 59 59 59 59 59 59
60 60
63 63
65
69
7
71 71 71 71 71
72
77 77
81
82
86
88
90
92 92
99
+ + + + + + + + + +
- put(k,v) psuedo code:
- Deleting an entry from a Skip List
- What you must do to the skip list to remove an entry:
- Before deletinng the entry 25:

- After deleting the entry 25:

(The whole column containing entries for 25 must be deleted !!!)
- Before deletinng the entry 25:
- Step-by-step to accomplish: remove(25)
- Before the deletion:

- Step 1: locate the desired element (at the lowest level of the skip list):

- While p != null, repeat these steps to remove the column:
- Unlink the element at p (by making the left neighbor and the right neighbor pointing to each other)

- Move p upward (prepare for loop)

- Unlink the element at p (by making the left neighbor and the right neighbor pointing to each other)
- Result of removal:

- Before the deletion:
- What you must do to the skip list to remove an entry:
- The Removal Algorithm
- Psuedo code:
p = findExntry(k); if (p.key != k)
return(null); // Not found, don't remove /* ------------------------------------------------------------
We are at level 0
Travel up the tower and link the left and right neighbors
------------------------------------------------------------ */
while ( p != null )
{
p.left.right = p.right;
p.right.left = p.left;
}
补充,jdk中有一个java.util.concurrent.ConcurrentSkipListMap,可以参考这个skiplist实现。
* @author Doug Lea
* @param <K> the type of keys maintained by this map
* @param <V> the type of mapped values
* @since 1.6
- Psuedo code:
Implementing the skip list data structure in java --reference的更多相关文章
- Data structure basics - Java Implementation
Stack & Queue Implementations FixedCapacityQueue package cn.edu.tsinghua.stat.mid_term; import j ...
- Java for LeetCode 211 Add and Search Word - Data structure design
Design a data structure that supports the following two operations: void addWord(word)bool search(wo ...
- ✡ leetcode 170. Two Sum III - Data structure design 设计two sum模式 --------- java
Design and implement a TwoSum class. It should support the following operations: add and find. add - ...
- LeetCode Two Sum III - Data structure design
原题链接在这里:https://leetcode.com/problems/two-sum-iii-data-structure-design/ 题目: Design and implement a ...
- hdu-5929 Basic Data Structure(双端队列+模拟)
题目链接: Basic Data Structure Time Limit: 7000/3500 MS (Java/Others) Memory Limit: 65536/65536 K (Ja ...
- LeetCode 笔记27 Two Sum III - Data structure design
Design and implement a TwoSum class. It should support the following operations: add and find. add - ...
- Summary: Trie Data Structure
Implement a Trie Data Structure, and search() & insert() function: we need to implement both Cla ...
- HDU 5929 Basic Data Structure 模拟
Basic Data Structure Time Limit: 7000/3500 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Oth ...
- hdu 4217 Data Structure? 树状数组求第K小
Data Structure? Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) ...
随机推荐
- webstorm下设置sass
关于sass,就不想多说什么了.只要你有css基础,十分钟入门好吗.可以参考下资料:http://www.w3cplus.com/sassguide/ 今天想说的是webStorm下如何实现sass自 ...
- Echarts显示全球dns server物理位置
今天YY给了我一大串dns server的ip,然后提出将这些ip物理位置显示在世界地图上(仅仅显示每个地区有几个dns server就好),苦逼了一下午,总算告一段落.把里面关键的点贴上来以后看.. ...
- python学习之subprocess模块
subprocess.Popen 这个模块主要就提供一个类Popen: class subprocess.Popen( args, bufsize=0, executable=None, stdin= ...
- Java-note-调试小技巧
使用 Eclipse 调试 Java 程序的 10 个技巧 英文原文:Again! – 10 Tips on Java Debugging with Eclipse 你应该看过一些如<关于调试的 ...
- css优先级判断
概念 浏览器是通过判断优先级,来决定到底哪些属性值是与元素最相关的,从而应用到该元素上.优先级是由选择器组成的匹配规则决定的. 如何计算? 优先级是根据由每种选择器类型构成的级联字串计算而成的. 它不 ...
- Activity生命周期与状态保存
弹出系统对话框,程序仍部分可见 onPause 对话框消失时 onResume 调用一个新的Activity,老的Activity不可见时 onPause->onStop 从新的Activi ...
- hadoop2.7【单节点】单机、伪分布、分布式安装指导
问题导读 1.从本文部署实际部署,总结本地模式.伪分布.分布式的区别是什么?2.单机是否是伪分布?3.本地模式是否可以运行mapreduce? 来源:about云 http://www.aboutyu ...
- mount失败
又一次遇到mount失败,提示文件系统类型错误.选项错误.有坏超级块等.之前是在ubuntu 14.04 lts desktop上挂载windows下共享文件夹遇到的.这次具体的环境如下:CentOS ...
- Apache Spark GraphX的简介
简单地说,GraphX是大规模图计算框架. GraphX 是 Spark 中的一个重要子项目,它利用 Spark 作为计算引擎,实现了大规模图计算的功能,并提供了类似 Pregel 的编程接口. Gr ...
- PC问题-(仅供备用)取消磁盘的自动扫描
问题现象:有一次整个单位停电了,之后再开机,每次电脑都自检.现在不想让电脑自检了. 问题原因:可能是因为停电,造成了系统文件的破坏. 问题处理:禁用电脑自检功能(注册表方法). Windows Reg ...