Skip List定義

Skip List 完整實(shí)現(xiàn)
//每個節(jié)點(diǎn)的數(shù)據(jù)結(jié)構(gòu)
typedef struct nodeStructure
{
int key;
int value;
struct nodeStructure *forward[1];
}nodeStructure;
//跳躍表的數(shù)據(jù)結(jié)構(gòu)
typedef struct skiplist
{
int level;
nodeStructure *header;
}skiplist;
下面是跳表的基本操作
節(jié)點(diǎn)的創(chuàng)建
nodeStructure* createNode(int level,int key,int value)
{
nodeStructure *ns=(nodeStructure *)malloc(sizeof(nodeStructure)+level*sizeof(nodeStructure*));
ns->key=key;
ns->value=value;
return ns;
}
列表的初始化
列表的初始化需要初始化頭部,并使頭部每層(根據(jù)事先定義的MAX_LEVEL)指向末尾(NULL)得运。
skiplist* createSkiplist()
{
skiplist *sl=(skiplist *)malloc(sizeof(skiplist));
sl->level=0;
sl->header=createNode(MAX_LEVEL-1,0,0);
for(int i=0;i<MAX_LEVEL;i++)
{
sl->header->forward[i]=NULL;
}
return sl;
}
插入元素
插入元素的時候元素所占有的層數(shù)完全是隨機(jī)的蛾默,通過隨機(jī)算法產(chǎn)生
int randomLevel()
{
int k=1;
while (rand()%2)
k++;
k=(k<MAX_LEVEL)?k:MAX_LEVEL;
return k;
}
跳表的插入需要三個步驟坪蚁,第一步需要查找到在每層待插入位置,然后需要隨機(jī)產(chǎn)生一個層數(shù),最后就是從高層至下插入两残,插入時算法和普通鏈表的插入完全相同裤纹。
bool insert(skiplist *sl,int key,int value)
{
nodeStructure *update[MAX_LEVEL];
nodeStructure *p, *q = NULL;
p=sl->header;
int k=sl->level;
//從最高層往下查找需要插入的位置
//填充update
for(int i=k-1; i >= 0; i--){
while((q=p->forward[i])&&(q->key<key))
{
p=q;
}
update[i]=p;
}
//不能插入相同的key
if(q&&q->key==key)
{
return false;
}
//產(chǎn)生一個隨機(jī)層數(shù)K
//新建一個待插入節(jié)點(diǎn)q
//一層一層插入
k=randomLevel();
//更新跳表的level
if(k>(sl->level))
{
for(int i=sl->level; i < k; i++){
update[i] = sl->header;
}
sl->level=k;
}
q=createNode(k,key,value);
//逐層更新節(jié)點(diǎn)的指針委刘,和普通列表插入一樣
for(int i=0;i<k;i++)
{
q->forward[i]=update[i]->forward[i];
update[i]->forward[i]=q;
}
return true;
}
紅色區(qū)域?yàn)檩o助數(shù)組update的內(nèi)容
刪除節(jié)點(diǎn)
刪除節(jié)點(diǎn)操作和插入差不多,找到每層需要刪除的位置服傍,刪除時和操作普通鏈表完全一樣钱雷。不過需要注意的是,如果該節(jié)點(diǎn)的level是最大的吹零,則需要更新跳表的level罩抗。
bool deleteSL(skiplist *sl,int key)
{
nodeStructure *update[MAX_LEVEL];
nodeStructure *p,*q=NULL;
p=sl->header;
//從最高層開始搜
int k=sl->level;
for(int i=k-1; i >= 0; i--){
while((q=p->forward[i])&&(q->key<key))
{
p=q;
}
update[i]=p;
}
if(q&&q->key==key)
{
//逐層刪除,和普通列表刪除一樣
for(int i=0; i<sl->level; i++){
if(update[i]->forward[i]==q){
update[i]->forward[i]=q->forward[i];
}
}
free(q);
//如果刪除的是最大層的節(jié)點(diǎn)灿椅,那么需要重新維護(hù)跳表的
for(int i=sl->level-1; i >= 0; i--){
if(sl->header->forward[i]==NULL){
sl->level--;
}
}
return true;
}
else
return false;
}
查找
跳表的優(yōu)點(diǎn)就是查找比普通鏈表快套蒂,當(dāng)然查找操作已經(jīng)包含在在插入和刪除過程,實(shí)現(xiàn)起來比較簡單茫蛹。
int search(skiplist *sl,int key)
{
nodeStructure *p,*q=NULL;
p=sl->header;
//從最高層開始搜
int k=sl->level;
for(int i=k-1; i >= 0; i--){
while((q=p->forward[i])&&(q->key<=key))
{
if(q->key==key)
{
return q->value;
}
p=q;
}
}
return NULL;
}


