之前不知道还有跳表这等数据结构,直到做到一个题要分析跳表的插入、删除等基本操作的时间复杂度,于是查阅资料写了个跳表的程序。跳表本质上是有序表,但是一种基于概率的有序表。
直接在单链表上查找某元素时间复杂度为O(n)。
但基于跳表的查找时间复杂度为O(log(n)),以空间换取时间。通过高层建立索引,达到加快查找的目的。
跳表具有如下性质:
(1)、跳表是有序链表;
(2)、若某元素出现在i层上,则一定出现在i-1层上,i>.1;
(3)、某节点有横向和纵向两个指针。
以上图片来自http://blog.sina.com.cn/s/blog_72995dcc01017w1t.html,在此致谢!
#include<iostream> #include<ctime> using namespace std; const int MAXN_LEVEL=10; struct SNode { int key; SNode *forword[MAXN_LEVEL]; }; struct SkipList { int nowLevel; SNode *head; }; /************************************************ *参数:myList为指向跳表头结点的指针 *功能:初始化跳表 *************************************************/ void InitSkipList(SkipList *& myList) { myList=new SkipList; myList->nowLevel=0; myList->head=new SNode; for(int i=0;i<MAXN_LEVEL;i++) myList->head->forword[i]=NULL; } /************************************************ *参数:myList为指向跳表头结点的指针,x为待插入元素,countRet为查找次数 *功能:在跳表中插入元素x *************************************************/ bool InsertSkipList(SkipList *myList,int val) { if(NULL==myList) return false; int k=myList->nowLevel; SNode *q,*p=myList->head; SNode *upDateNode[MAXN_LEVEL]; while(k>=0) { q=p->forword[k]; while(NULL!=q&&q->key<val) { p=q; q=p->forword[k]; } if(NULL!=q&&q->key==val) return false; upDateNode[k]=p; --k; } k=rand()%(MAXN_LEVEL-1); if(k>myList->nowLevel) { k=++myList->nowLevel; upDateNode[k]=myList->head; } p=new SNode; p->key=val; for(int i=0;i<=k;i++) { q=upDateNode[i];//q指向前面小于x的 p->forword[i]=q->forword[i]; q->forword[i]=p; } //for(int i=k+1;i<=myList->nowLevel;i++) for(int i=k+1;i<MAXN_LEVEL;i++) p->forword[i]=NULL; return true; } /************************************************ *参数:myList为指向跳表头结点的指针,x为待查找元素,countRet为查找次数 *功能:查找跳表中是否存在元素x *************************************************/ SNode* FindSkipList(SkipList * myList,int val,int &countRet) { if(NULL==myList) return NULL; int k=myList->nowLevel; SNode *q,*p=myList->head; while(k>=0) { q=p->forword[k]; ++countRet; while(NULL!=q&&q->key<val) { ++countRet; p=q; q=p->forword[k]; } if(NULL!=q&&q->key==val) return q; --k; } return NULL; } /************************************************ *参数:myList为指向跳表头结点的指针,x为待删除元素 *功能:删除跳表中元素x *************************************************/ bool DeleteSkipList(SkipList * myList,int val) { int tmpCountRet=0; SNode *ret=FindSkipList(myList,val,tmpCountRet); if(NULL==ret) return false; int k=myList->nowLevel; SNode *q,*p=myList->head; SNode *upDateNode[MAXN_LEVEL]; for(int i=0;i<MAXN_LEVEL;i++) upDateNode[i]=NULL; while(k>=0) { q=p->forword[k]; while(NULL!=q&&q->key<val) { p=q; q=p->forword[k]; } if(NULL!=q&&q->key==val) upDateNode[k]=p; --k; } for(int i=0;i<=myList->nowLevel;i++) { q=upDateNode[i];//q指向前面小于x if(NULL!=q&&q->forword[i]==ret) q->forword[i]=ret->forword[i]; } delete ret; return true; } int main() { int val; SkipList * myList; InitSkipList(myList); while(cin>>val) { if(!InsertSkipList(myList,val)) cout<<val<<"插入失败!"<<endl; else cout<<val<<"插入成功!"<<endl; /* int countRet=0; if(NULL!=FindSkipList(myList,val,countRet)) cout<<val<<"查找成功!"<<endl; else cout<<val<<"查找失败!"<<endl; cout<<"共查找了"<<countRet<<"次"<<endl; */ /* DeleteSkipList(myList,val); countRet=0; if(NULL!=FindSkipList(myList,val,countRet)) cout<<val<<"查找成功!"<<endl; else cout<<val<<"查找失败!"<<endl; cout<<"共查找了"<<countRet<<"次"<<endl; */ } system("Pause"); }
原文:http://blog.csdn.net/xj2419174554/article/details/22979543