雖然avl樹和紅黑樹在數據搜索和排序方面都是有效的數據結構,但是都顯得特別麻煩,跳躍表就顯得特別簡單,雖然簡單 不影響他性能,在平均情況下,其插入、刪除、查找數據時間復雜度都是O(log(N)),其最壞情況下都為O(N)。 跳躍表的構造源於一種用於查找的基礎數據結構---鏈表。跳躍表就是在普通鏈表的情況下,隨機在一些節點上增加幾層鏈,用於指向后面的數據。
普通鏈表 :
跳躍表:
鏈表就像走樓梯,普通鏈表一步一個階梯,但是跳躍表可以達到一步好多個階梯。所以效率比普通鏈表快多了。
跳躍表實現需要兩個類:一個節點類和一個跳躍表本身的類。
=代碼如果出錯,歡迎指出=
節點類代碼:
public class SkipNode
{
public int key;
public Object value;
public SkipNode[] link;
public SkipNode(int level,int key , Object Value)
{
this.key=key;
this.value=value;
link=new SkipNode[level];
}
跳躍表類代碼:
public class SkipList
{
private int maxLevel;
private int level;
private SkipNode header;
private const int NIL=Int32.MaxValue;
private const int PROB =0.5F;
}
SkipList類的構造器包含兩個部分:帶單獨一個參數的Public構造器,其中此參數是跳躍表內節點的總數量,以及一個完成大部分工作的Private構造器數。
代碼如下:
public SkipList(long maxNodes) //把節點總數量傳遞給構造器方法作為方法內的唯一參數。初始化跳躍表對象工作的,private構造器在調用時會有兩個參數
{
this.SkipList2(PROB,(int)(Math.Ceiling(Math.Log(maxNodes)/Math.Log(1/PROB)-1)));
}
private void SkipList2(float probable,int maxLevel) //設置了數據成員的數值,創建了跳躍表的頭節點,創建了用於每個節點鏈的“空”節點,記憶初始化了該元素的鏈
{
this.proability=probable;
this.maxLevel=maxLevel;
level=0;
header=new SkipNode(maxLevel,0,null);
SkipNode nilElement=new Skip(maxLevel,NIL,null);
for(int i=0;i<=maxLevel-1;i++)
header.link[i]=nilElement;
}
概率方法代碼:
private int GenRandomLevel() //隨機給鏈層數
{
int newLevel=0;
Random r= new Random();
int ran=r.Next(0);
while((newLevel<maxLevel)&&ran<provavility))
newLevel++;
return newLevel;
}
插入代碼:
public void insert(int key,Object value)
{
SkipNode[] update=new SkipNode[maxLevel];
SkipNode cursor=header;
for( int i=level;i>=level;i--) //從當前最高層到最底層
{
while (cursor.link[i].key<key) //如果比要找的這個數值要小的話,就到指向下一個節點,用update【i】來接收每一層的最后一個節點
cursor=cursor.link[i];
update[i]=cursor;
}
cursor=cursor.link[0];
if (cursor.key=key) //如果存在,那就覆蓋
cursor.value=value;
else
{
int newLevel =GenRandomLevel();
if (newLevel>level) //如果隨機出來的鏈層比當前鏈層高的情況
{
for(int i=level+1;i<=newLevel-1;i++)
update[i]=header;
level=newLevel;
}
cursor = new SkipNode(newLevel,key,Value); // 插入
for(int i=0;i<=newLevel-1;i++) //插入后改變自己的鏈指向的節點,和前面節點的鏈指向的節點變成自己
{
cursor.link[i]=update[i].link[i];
update[i].link[i]=cursor;
}
}
}
刪除代碼:
public void Delete(int key)
{
SkipNode[] update=new SkipNode[maxLevel+1];
SkipNode cursor=header;
for(Int i=level;i>=level;i--)
{
while(cursor.link[i].key<key)
cursor=cursor.link[i];
update[i]=cursor;
}
cursor=cursor.link[0];
if(cursor.key==key)
{
for(int i=0;i<level-1;i++)
if(update[i].link[i]==cursor)
update[i].link[i]=cursor.link[i]; //直接等於要刪除節點的后面節點
while((level>0)&&(header.link[level].key==NIL)) //刪除當前節點的鏈層
level--;
}
}
遍歷代碼:
public Object Search(int key)
{
SkipNode cursor=header;
for(int i=level;i>0;i--)
{
SkipNode nexeElement=cursor.link[i];
while(nextElement.key<key)
{
cursor=nextElement;
nextElement=cursor.link[i];
}
}
cursor=cursor.link[0];
if(cursor.key==key)
return cursor.value;
else
return "Object not found";
}
csdn搬家