Java SkipList 实现

来源:互联网 发布:怎么更换路由器mac地址 编辑:程序博客网 时间:2024/06/05 01:05
package datastruct;import java.util.Random;public class SkipList {public SkipListEntry head,tail;public int n;//sizepublic int h;//highpublic Random r;public SkipList(){SkipListEntry p1,p2;p1 = new SkipListEntry(Integer.MIN_VALUE);p2 = new SkipListEntry(Integer.MAX_VALUE);p1.right = p2;p2.left = p1;head = p1;tail = p2;n = 0;h = 0;r = new Random();}public Integer get(Integer k){SkipListEntry p = findEntry(k);return p.value == k ? p.value : null;}public void put(Integer k){SkipListEntry p = findEntry(k);if (p.value == k){//已有了 就不插入了return;}//insert k with random heightSkipListEntry q = new SkipListEntry(k);q.left = p;q.right = p.right;p.right.left = q;p.right = q;int i = 0;while (r.nextDouble() < 0.5){if (i>=h){addLayer();}while (p.up == null){p = p.left;}p = p.up;SkipListEntry e = new SkipListEntry(k);e.left = p;e.right = p.right;e.down = q;p.right.left = e;p.right = e;q.up = e;q = e;i = i+1;}n = n+1;}public void remove(Integer k){SkipListEntry p = findEntry(k);if (p.value != k){return;}while (p!=null){p.left.right = p.right;p.right.left = p.left;p = p.up;}}public void list(){for (int i=1;i<=h;i++){SkipListEntry p = head;for (int j=1;j<=i;j++){p = p.down;}while (p.right!=null && p.right.value!=Integer.MAX_VALUE){p = p.right;System.out.print(p.value + "->");}System.out.println();}}private void addLayer(){SkipListEntry p1,p2;p1 = new SkipListEntry(Integer.MIN_VALUE);p2 = new SkipListEntry(Integer.MAX_VALUE);p1.right = p2;p1.down = head;p2.left = p1;p2.down = tail;head.up = p1;tail.up = p2;head = p1;tail = p2;h ++;}/** * 查找节点 * @param k 待查找的节点值 * @return 节点,如果没有匹配的值,那么应该是离待插入位置最近的节点,在层1 */private SkipListEntry findEntry(Integer k){SkipListEntry p ;p = head;while (true){/** * eg:k = 34 *  * 10 -> 20 ->30 -> 40 *   ^ *   p is here */while (p.right.value!=Integer.MAX_VALUE && p.right.value <= k){p = p.right;}if (p.down!=null){p = p.down;}else{break;}}return p;}/** * @param args */public static void main(String[] args) {int COUNT = 100;SkipList l = new SkipList();Random r = new Random();int remove = 0,v;for (int i=0;i<COUNT/10;i++){v = r.nextInt(COUNT);if (i == COUNT/10-2){remove = v; System.out.println("remove:" + remove);}l.put(v);}l.list();l.remove(remove);System.out.println("After:");l.list();}}class SkipListEntry{Integer value;SkipListEntry up,down,left,right;public SkipListEntry(Integer value) {super();this.value = value;}}

参考:http://www.mathcs.emory.edu/~cheung/Courses/323/Syllabus/Map/skip-list-impl.html

相比红黑树:http://stackoverflow.com/questions/256511/skip-list-vs-binary-tree

  • Locking skip lists are insanely fast. They scale incredibly well with the number of concurrent accesses. This is what makes skip lists special, other lock based data structures tend to croak under pressure.
  • Lock-free skip lists are consistently faster than locking skip lists but only barely.
  • transactional skip lists are consistently 2-3 times slower than the locking and non-locking versions.
  • locking red-black trees croak under concurrent access. Their performance degrades linearly with each new concurrent user. Of the two known locking red-black tree implementations, one essentially has a global lock during tree rebalancing. The other uses fancy (and complicated) lock escalation but still doesn't significantly out perform the global lock version.
  • lock-free red-black trees don't exist (no longer true, see Update).
  • transactional red-black trees are comparable with transactional skip-lists. That was very surprising and very promising. Transactional memory, though slower if far easier to write. It can be as easy as quick search and replace on the non-concurrent version.
写过一段代码,大多数情况下,SkipList的性能都优于JDK 的 TreeMap实现(基于红黑树)

0 0
原创粉丝点击