Java SkipList 实现

package datastruct;

import java.util.Random;

public class SkipList {

	public SkipListEntry head,tail;
	public int n;//size
	public int h;//high
	public 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 height
		SkipListEntry 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实现(基于红黑树)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值