跳躍表:就是將線性鏈表的指針改變成多個,使得可以跳躍中間的一些結點
該算法可以很快的提高搜索效率,本人認爲本質上還是與哈希散列表一致
#include "stdafx.h"
#include "targetver.h"
#include <stdio.h>
#include <tchar.h>
#include "stdafx.h"
#include"iostream"
#include<math.h>
#include<time.h>
#include<iomanip>
using namespace std;
const unsigned long maxshort=65535L;
const unsigned long multiplier=1194211693L;
const unsigned long adder=12345L;
class RandomNumber{
private:
//當前種子
unsigned long randSeed;
public:
//構造函數
RandomNumber(unsigned long s=0);
unsigned short Random(unsigned long n);
double fRandom();
};
RandomNumber::RandomNumber(unsigned long s)
{
if(s==0)
randSeed=time(0);
else
randSeed=s;
}
double RandomNumber::fRandom()
{
return Random(maxshort)/double(maxshort);
}
unsigned short RandomNumber::Random(unsigned long n)
{
randSeed=multiplier*randSeed+adder;
return (unsigned short)((randSeed>>16)%n);
}
template<class EType,class KType>class SkipList;
template<class EType,class KType>
class SkipNode
{
friend SkipList<EType,KType>;
private:
SkipNode(int size)//構造函數
{
next=new SkipNode<EType,KType>*[size];
}
~SkipNode()//析構函數
{
delete[] next;
}
EType data;
SkipNode<EType,KType>**next;//指針數組
};
template<class EType,class KType>
class SkipList
{
public:
SkipList(KType Large,int MaxE=10000,float p=0.5);//構造函數
~SkipList();//析構函數
bool Search(const KType &k,EType &e)const;//查找操作
SkipList<EType,KType>&Insert(const EType &e);//插入操作
SkipList<EType,KType>&Delete(const KType &k,EType &e);//刪除操作
void Output();//輸出所有元素
private:
int Level();
SkipNode<EType,KType>*SaveSearch(const KType &k);
int MaxLevel;//跳躍表級別上界
int Levels;//當前最大級別
RandomNumber rnd;
float Prob;//分配結點級別
KType TailKey;//元素鍵值上界
SkipNode<EType,KType> *head;//頭結點指針
SkipNode<EType,KType> *NIL;//尾結點指針
SkipNode<EType,KType> **last;//指針數組
};
template<class EType,class KType>
SkipList<EType,KType>::SkipList(KType Large,int MaxE,float p)//構造函數
{
Prob=p;
MaxLevel=8;//ceil(log(MaxE)/log(1/p))-1;
TailKey=Large;
Levels=0;
head=new SkipNode<EType,KType>(MaxLevel+1);
NIL=new SkipNode<EType,KType>(0);
last=new SkipNode<EType,KType>*[MaxLevel+1];
NIL->data=Large;
//將跳躍表初始化爲空表
for(int i=0;i<=MaxLevel;i++)
head->next[i]=NIL;
}
template<class EType,class KType>
SkipList<EType,KType>::~SkipList(void)
{//析構函數
SkipNode<EType,KType> *next;
//刪除所有結點
while(head!=NIL)
{
next=head->next[0];
delete head;
head=next;
}
delete NIL;
delete []last;
}
class element
{
friend void main(void);
public:
operator long()const{return key;}
element& operator=(long y)
{
key=y;
return *this;
}
private:
int data;
long key;
};
template<class EType,class KType>
bool SkipList<EType,KType>::Search(const KType& k,EType &e)const
{
if(k>=TailKey)return false;
SkipNode<EType,KType> *p=head;
for(int i=Levels;i>=0;i--)
while(p->next[i]->data<k)
p=p->next[i];
e=p->next[0]->data;
return (e==k);
}
template<class EType,class KType>
SkipNode<EType,KType>*SkipList<EType,KType>::SaveSearch(const KType &k)
{
SkipNode<EType,KType> *p=head;
for(int i=Levels;i>=0;i--)
{
while(p->next[i]->data<k)
p=p->next[i];
last[i]=p;
}
return (p->next[0]);
}
template<class EType,class KType>
int SkipList<EType,KType>::Level()
{
//
int lev=0;
while(rnd.fRandom()<Prob)lev++;
return (lev<=MaxLevel)?lev:MaxLevel;
}
template<class EType,class KType>
SkipList<EType,KType>&SkipList<EType,KType>::Insert(const EType& e)
{
KType k=e;
//if(k>=TailKey)
//throw BadInput();
//return ;
SkipNode<EType,KType> *p=SaveSearch(k);
//if(p->data==e)
//throw BadInput();
//return ;
int lev=Level();
if(lev>Levels)
{
for(int i=Levels+1;i<=lev;i++)
last[i]=head;
Levels=lev;
}
SkipNode<EType,KType> *y=new SkipNode<EType,KType>(lev+1);
y->data=e;
for(int i=0;i<=lev;i++)
{
y->next[i]=last[i]->next[i];
last[i]->next[i]=y;
}
return *this;
}
template<class EType,class KType>
SkipList<EType,KType>&SkipList<EType,KType>::Delete(const KType &k, EType &e)
{
// if(k>=TailKey) throw BadInput();
SkipNode<EType,KType> *p=SaveSearch(k);
// if(p->data!=k)
// throw BadInput();
for(int i=0;i<=Levels&&last[i]->next[i]==p;i++)
last[i]->next[i]=p->next[i];
while(Levels>0&&head->next[Levels]==NIL)
Levels--;
e=p->data;
delete p;
return *this;
}
template<class EType,class KType>
void SkipList<EType,KType>::Output(void)
{
SkipNode<EType,KType> *y=head->next[0];
for(;y!=NIL;y=y->next[0])
cout<<y->data<<" ";
cout<<endl;
}
int _tmain(int argc, _TCHAR* argv[])
{
int e;
SkipList<int,long> L(100,6,0.5);
L.Insert(2);
L.Insert(3);
L.Insert(5);
L.Insert(7);
L.Insert(11);
L.Insert(13);
L.Insert(17);
L.Insert(19);
L.Insert(23);
L.Insert(4);
L.Delete(7,e);
L.Output();
cout<<endl<<e;
system("PAUSE");
}