[算法天天见](五)跳跃链表

跳跃链表

一、概述

跳表实际上是链表的一种扩展,它解决的是链表的查找速度问题。由于它是链表的扩展,所以他底层维护的本质还是一个有序链表。他的复杂度取决于什么样的node插入到最高哪层中。在插入的时候下从最高层开始找起,一直找到最底层,然后用一个函数算出这个节点要插入到几层,最后再每一层执行插入操作。查找和插入前半部分是同一个操作。删除节点也很简单,因为你找到的节点总是最上层节点,只要循环删除下层本节点就可以了。

二、算法

public class SkipListTest extends Sprite
{
	private var mMaxLayer:uint = 4;
	private var mSkipRoot:Vector.<SkipNode> = new Vector.<SkipNode>(4);
	private var nodeHead:Node = new Node();
	public function SkipListTest()
	{
		super();
		init();			
		
		var a:Array = [10,30,20,50,40];
		for(var i:int = 0; i < a.length; i++)
		{
			this.insert(a[i]);
		}
		print();
		
	}
	
	private function init():void
	{
		//初始化头结点
		for(var i:int = 0; i < mMaxLayer; i++)
		{
			mSkipRoot[i] = new SkipNode();
			mSkipRoot[i].data = nodeHead;
			if(i > 0)
			{
				mSkipRoot[i].down = mSkipRoot[i - 1];
			}
		}
	}
	
	public function search(value:int):SkipNode
	{
		var prev:Vector.<SkipNode> = new Vector.<SkipNode>(4);//上一个节点
		var cur:Vector.<SkipNode> = new Vector.<SkipNode>(4);//当前查找的节点
		var i:int;
		for(i = 0; i < mMaxLayer; i++)
		{
			prev[i] = mSkipRoot[i];
			cur[i] = prev[i].next;
		}
		i = mMaxLayer - 1;
		do
		{
			
			if(cur[i] == null)
			{
				i--;
			}else
			{
				if(cur[i].data.data > value)//在下层查找
				{
					i--;
					if(i >=0 )
					{
						prev[i] =prev[i + 1].down;
						cur[i] = prev[i].next;
					}
				}else if(cur[i].data.data < value)//继续在本层查找
				{
					prev[i] = cur[i];
					cur[i] = prev[i].next;
					
				}else
				{
					return cur[i];
				}
			}
			
		}while( i >= 0);
			
		return null;
	}
	
	public function insert(value:int):void
	{
		var prev:Vector.<SkipNode> = new Vector.<SkipNode>(4);//上一个节点
		var cur:Vector.<SkipNode> = new Vector.<SkipNode>(4);//当前查找的节点
		var newNode:Node;
		var newSkipNode:SkipNode;
		var i:int;
		for(i = 0; i < mMaxLayer; i++)
		{
			prev[i] = mSkipRoot[i];
			cur[i] = prev[i].next;
		}
		i = mMaxLayer - 1;
		do
		{

			if(cur[i] == null)
			{
				i--;
			}else
			{
				if(cur[i].data.data > value)//在下层查找
				{
					i--;
					if(i >=0 )
					{
						prev[i] =prev[i + 1].down;
						cur[i] = prev[i].next;
					}
				}else if(cur[i].data.data < value)//继续在本层查找
				{
					prev[i] = cur[i];
					cur[i] = prev[i].next;
					
				}else//不保存相同值
				{
					return;
				}
			}
			
		}while( i >= 0)
		
		newNode = new Node();
		newNode.data = value;
		
		//看要插入几层
		var layer:uint = randomLayer();
		//对每一层进行插入
		for(var j:int = 0; j <= layer; j++)
		{
			newSkipNode = new SkipNode();
			newSkipNode.data = newNode;
			newSkipNode.next = prev[j].next;
				prev[j].next = newSkipNode;
			if(j > 0)
			{
				newSkipNode.down = prev[j - 1].next;
			}
		}
	}
	
	public function remove(value:int):void
	{
		//remove 其实很简单了 因为 search 可以做到同时返回node与node的前驱
		//偷下懒应该没人发现吧....
	}
	
	private function randomLayer():uint
	{
		return Math.floor(Math.random() * 4);
	}
	
	public function print():void
	{
		for(var i:int = mSkipRoot.length - 1; i >= 0 ; --i)
		{
			var s:String = "";
			s += "第" + i + "行: ";
			var cur:SkipNode = mSkipRoot[i];
			while(cur != null)
			{
				s += cur.toString() + ", ";
				cur = cur.next;
			}
			trace(s);
		}
	}
}


class SkipNode
{
	public var data:Node;//引用的那个Node
	public var next:SkipNode;//下一个Node
	public var down:SkipNode;//下一级指向的Node
	
	public function toString():String
	{
		return data.toString();
	}
}

class Node
{
	public var data:int;
	public var next:Node;
	public function Node()
	{
		
	}
	
	public function toString():String
	{
		return data.toString();
	}
}
点赞