這是我設計的跳錶數據結構,能正常運行,當然也存在缺點:level1層的down指針恆爲空且操作略有不同。
首先是我的跳錶的結構。
數據結點
typedef struct nodestructure//數據結點結構
{
int key;//關鍵字
int value; //value值
int level; //記錄這個結點的層數
}nodestructure;
數據包含key,value,level。Key相當於這個結點的ID,value相當於數據,本程序允許根據key來查找value的值,level對用戶看不見,用於刪除結點時找到待刪結點最高的跳錶結點。
跳錶結點
typedef struct skiplist//跳錶結點
{
skiplist *right;//可以找到本層下一個跳錶結點
skiplist *down;//可以找到下一層跳錶結點
nodestructure *header;//可以找到本跳錶結點對應的數據結點
}skiplist;
創建數據結點
nodestructure *createnode(int key,int value)//創建數據結點
{
nodestructure*ns=(nodestructure *)malloc(sizeof(nodestructure));
ns->key=key;
ns->value=value;
returnns;
}
創建頭結點
skiplist *createskiplist()//創建一個頭結點
{
nodestructure *ns=createnode(0,0);
skiplist*sl=NULL;
skiplist*temp=NULL;
ns->level=maxlevel;
for(inti=1;i<=maxlevel;i++)
{
sl=(skiplist*)malloc(sizeof(skiplist));
sl->right=NULL;
if(i==1)sl->down=NULL;
elsesl->down=temp;
sl->header=ns;
temp=sl;
}
return sl;
}
隨機層數
int randomlevel()//層數隨機
{
int k=1;
while (rand()%2)
k++;
k=(k<maxlevel)?k:maxlevel;
return k;
}
插入一個結點
bool insertskiplist(skiplist *sl,int key,int value)//插入結點
{
nodestructure*ns=createnode(key,value);
skiplist*p,*q=NULL;
skiplist*update=NULL;
p=sl;
for(int i=maxlevel;i>=1;i--)
{
while((q=p->right)&&(q->header->key<key))
{
p=q;
}
p=p->down;
}
if(q&&q->header->key==key)
{
printf("插入失敗!已有該元素!\n");
return false;
}
int k=randomlevel();
ns->level=k;
for(inti=1;i<=k;i++)
{
p=(skiplist*)malloc(sizeof(skiplist));
p->right=NULL;
if(i!=1)p->down=q;
elsep->down=NULL;
p->header=ns;
q=p;
}
update=p;
p=sl;
for(int i=maxlevel;i>k;i--)
{
p=p->down;
}
for(int i=k;i>=1;i--)
{
while((q=p->right)&&(q->header->key<key))
{
p=q;
}
p->right=update;
update->right=q;
update=update->down;
p=p->down;
}
returntrue;
}
根據key值搜索相應value值
void searchskiplist(skiplist *sl,int key)
{
skiplist*p=sl;
skiplist*q=NULL;
for(inti=maxlevel;i>=1;i--)
{
while((q=p->right)&&(q->header->key<key))
{
p=q;
}
p=p->down;
}
if(q&&q->header->key==key)
printf("查找成功!value爲:%d。\n",q->header->value);
else
printf("查找失敗!沒有該元素!\n");
}
根據key值刪除相應結點
bool deleteskiplist(skiplist *sl,int key)
{
skiplist*p=sl;
skiplist*q=NULL;
nodestructure*ns=NULL;
for(inti=maxlevel;i>=1;i--)
{
while((q=p->right)&&(q->header->key<key))
{
p=q;
}
p=p->down;
}
if((q==NULL)||(q->header->key!=key))
{
printf("刪除失敗!沒有該元素!\n");
returnfalse;
}
elseif(q->header->key==key)
{
intk=q->header->level;
ns=q->header;
free(ns);
p=sl;
for(inti=maxlevel;i>k;i--)
{
p=p->down;
}
for(int i=k;i>=1;i--)
{
while((q=p->right)&&(q->header->key<key))
{
p=q;
}
p->right=q->right;
free(q);
p=p->down;
}
printf("刪除成功!\n");
return true;
}
}
輸出整張表
void printskiplist(skiplist *sl)//打印整張表
{
skiplist *q=sl;
skiplist *p=q->right;
for(inti=maxlevel;i>=1;i--)
{
while(p)
{
printf("%d->",p->header->value);
p=p->right;
}
if(q->down)q=q->down;
p=q->right;
printf("\n");
}
}
完整代碼:
#include<stdio.h>
#include<stdlib.h>
#define maxlevel 10
typedef struct nodestructure//數據結點結構
{
int key;//關鍵字
int value; //value值
int level;//記錄這個結點的層數
}nodestructure;
typedef struct skiplist//跳錶結點
{
skiplist *right;//可以找到本層下一個跳錶結點
skiplist *down;//可以找到下一層跳錶結點
nodestructure *header;//可以找到本跳錶結點對應的數據結點
}skiplist;
nodestructure *createnode(int key,int value)//創建數據結點
{
nodestructure*ns=(nodestructure *)malloc(sizeof(nodestructure));
ns->key=key;
ns->value=value;
return ns;
}
skiplist *createskiplist()//創建一個頭結點
{
nodestructure *ns=createnode(0,0);
skiplist *sl=NULL;
skiplist *temp=NULL;
ns->level=maxlevel;
for(inti=1;i<=maxlevel;i++)
{
sl=(skiplist*)malloc(sizeof(skiplist));
sl->right=NULL;
if(i==1)sl->down=NULL;
else sl->down=temp;
sl->header=ns;
temp=sl;
}
return sl;
}
int randomlevel()//層數隨機
{
int k=1;
while (rand()%2)
k++;
k=(k<maxlevel)?k:maxlevel;
return k;
}
bool insertskiplist(skiplist *sl,int key,int value)//插入結點
{
nodestructure *ns=createnode(key,value);
skiplist *p,*q=NULL;
skiplist *update=NULL;
p=sl;
for(int i=maxlevel;i>=1;i--)
{
while((q=p->right)&&(q->header->key<key))
{
p=q;
}
p=p->down;
}
if(q&&q->header->key==key)
{
printf("插入失敗!已有該元素!\n");
return false;
}
int k=randomlevel();
ns->level=k;
for(inti=1;i<=k;i++)
{
p=(skiplist*)malloc(sizeof(skiplist));
p->right=NULL;
if(i!=1)p->down=q;
else p->down=NULL;
p->header=ns;
q=p;
}
update=p;
p=sl;
for(int i=maxlevel;i>k;i--)
{
p=p->down;
}
for(int i=k;i>=1;i--)
{
while((q=p->right)&&(q->header->key<key))
{
p=q;
}
p->right=update;
update->right=q;
update=update->down;
p=p->down;
}
return true;
}
void searchskiplist(skiplist *sl,int key)
{
skiplist *p=sl;
skiplist *q=NULL;
for(inti=maxlevel;i>=1;i--)
{
while((q=p->right)&&(q->header->key<key))
{
p=q;
}
p=p->down;
}
if(q&&q->header->key==key)
printf("查找成功!value爲:%d。\n",q->header->value);
else
printf("查找失敗!沒有該元素!\n");
}
bool deleteskiplist(skiplist *sl,int key)
{
skiplist *p=sl;
skiplist *q=NULL;
nodestructure*ns=NULL;
for(int i=maxlevel;i>=1;i--)
{
while((q=p->right)&&(q->header->key<key))
{
p=q;
}
p=p->down;
}
if((q==NULL)||(q->header->key!=key))
{
printf("刪除失敗!沒有該元素!\n");
return false;
}
else if(q->header->key==key)
{
intk=q->header->level;
ns=q->header;
free(ns);
p=sl;
for(inti=maxlevel;i>k;i--)
{
p=p->down;
}
for(int i=k;i>=1;i--)
{
while((q=p->right)&&(q->header->key<key))
{
p=q;
}
p->right=q->right;
free(q);
p=p->down;
}
printf("刪除成功!\n");
return true;
}
}
void printskiplist(skiplist *sl)//打印整張表
{
skiplist *q=sl;
skiplist *p=q->right;
for(int i=maxlevel;i>=1;i--)
{
while(p)
{
printf("%d->",p->header->value);
p=p->right;
}
if(q->down)q=q->down;
p=q->right;
printf("\n");
}
}
int main()
{
skiplist *sl=createskiplist();
int x,k,key,value;
while(1)
{
printf("--------跳錶小程序--------\n");
printf("--------------------------\n");
printf("1.錄入跳錶\n");
printf("2.查找ID\n");
printf("3.刪除ID\n");
printf("4.打印跳錶\n");
printf("5.退出跳錶\n");
printf("--------------------------\n");
printf("按數字鍵執行操作\n");
scanf("%d",&x);
if(x==1)
{
printf("錄入跳錶\n");
printf("--------------------------\n");
printf("請輸入錄入個數:");
scanf("%d",&k);
for(inti=1;i<=k;i++)
{
printf("請輸入第%d個元素的key值和value值:\n",i);
scanf("%d%d",&key,&value);
insertskiplist(sl,key,value);
}
printf("\n");
}
else if(x==2)
{
printf("查找ID\n");
printf("--------------------------\n");
printf("請輸入ID:\n");
scanf("%d",&k);
searchskiplist(sl,k);
printf("\n");
}
else if(x==3)
{
printf("刪除ID\n");
printf("--------------------------\n");
printf("請輸入要刪除的ID:\n");
scanf("%d",&k);
deleteskiplist(sl,k);
printf("\n");
}
else if(x==4)
{
printf("打印跳錶\n");
printf("--------------------------\n");
printskiplist(sl);
printf("\n");
}
else if(x==5)
break;
else printf("輸入無效,請重新輸入!\n\n");
}
return 0;
}