An implementation of Skip list
来源:互联网 发布:python socketserver 编辑:程序博客网 时间:2024/05/16 07:10
随着redis和leveldb的火爆,Skip List(跳表)也火了起来,关于skip list的基础,自己google。skip list和B树、红黑树之类的平衡树有着同样的效果,但是skip list是一种超级简单而优雅的结构,实现B树,我们可能需要查阅很多资料,考虑很多细节,但是跳表完全可以在半个小时之类完成。
下面是我的实现,有参考了网上的一些代码:
#ifndef SKIPLIST_H_#define SKIPLIST_H_#include <stdio.h>#include <stdlib.h>#include <time.h>#define MAXLEVEL 24 /*max level of the skip list*/ /*the number of the MAXLEVEL is up to the dataset*/typedef int T; /*define the type of the data to be stored*/typedef struct _Node{T data;struct _Node *next[1]; /*next[i] point to the next node in level i*/}Node;typedef struct _skiplist{int levelnum; /*current level number of the skip list*/int num[MAXLEVEL]; /*the number of nodes of each level*/Node *head; /*head point to a Node of max level next[]*/}skiplist;skiplist list;#define END list.headvoid init(){list.head = (Node *)malloc(sizeof(Node) + (MAXLEVEL-1)*sizeof(Node*));int i;for(i=0; i<MAXLEVEL; i++){list.head->next[i] = END;list.num[i] = 0;}list.levelnum = -1;}int find(T data){Node *x = list.head;int i;for(i=list.levelnum; i>=0; i--){while(x->next[i]!=END && x->next[i]->data<data)x = x->next[i];}if(x->next[0]!=END && x->next[0]->data==data)return 1;return 0;}Node *insert(T data){Node *x = list.head;Node *pre[MAXLEVEL];int i;for(i=list.levelnum; i>=0; i--){ /*find the position to insert*/while(x->next[i]!=END && x->next[i]->data<data)x = x->next[i];pre[i] = x; /*record the pre-insert position of each level*/ }if(x->next[0]!=END && x->next[0]->data==data)return x->next[0];int insertLevel =0; /*generate a random insert level*///while(rand()%2==1 && ++insertLevel<MAXLEVEL-1); /*rand()%2 ==1, the insertlevel can never reach 16,why??*/ while(rand()<RAND_MAX/2 && ++insertLevel<MAXLEVEL-1);if(insertLevel > list.levelnum){for(i=insertLevel; i>list.levelnum; i--){pre[i] = END;}list.levelnum = insertLevel;}Node *newNode = (Node *)malloc(sizeof(Node) + (insertLevel)*sizeof(Node *));newNode->data = data;for(i=insertLevel; i>=0; i--){newNode->next[i] = pre[i]->next[i];pre[i]->next[i] = newNode;list.num[i]++;}return newNode;}void remove(T data){Node *x = list.head;Node *pre[MAXLEVEL];int i;for(i=list.levelnum; i>=0; i--){ /*find the position to delete*/while(x->next[i]!=END && x->next[i]->data<data)x = x->next[i];pre[i] = x; /*record the pre-insert position of each level*/ }if(x->next[0]==END || x->next[0]->data!=data)return;x = x->next[0];/*WOW...Wow...!!!!!, x->next[0] should be stored in x, otherwile x->next[0] will be modified by pre[]*/for(i=0; i<=list.levelnum; i++){if(pre[i]->next[i] != x)break;pre[i]->next[i] = x->next[i];list.num[i]--;}free(x);for(i=list.levelnum; i>=0; i--){ /*update the levelnum, discard the empty level*/if(list.head->next[i]!=END)break;list.levelnum--;}}void printlist(){int i;for(i=list.levelnum; i>=0; i--){Node *x = list.head;printf("%d Head--->",i);while(x->next[i] != END){printf("%d---->",x->next[i]->data);x = x->next[i];}printf("End\n\n");}}void printOneLevel(int level){if(level > list.levelnum){printf("level is valid(larger than the current level of the list\n");return;}Node *x = list.head;printf("%d Head--->",level);while(x->next[level] != END){printf("%d---->",x->next[level]->data);x = x->next[level];}printf("End\n\n");}#endif
#include <stdio.h>#include <stdlib.h>#include <string.h>#include "skiplist.h"#define TESTNUM 20extern skiplist list;int main(){srand(time(0));init();//for(int i=0; i<TESTNUM; i++)//insert(rand()%TESTNUM);//insert(2);//insert(2);//insert(9);////printf("%d,%d\n",list.levelnum,find(2));//printlist();//for(int i=list.levelnum; i>=0; i--)//printf("%d--->%d\n",i,list.num[i]);//remove(2);//remove(9);//remove(10);//printf("-----------------------------------\n");//printlist();//for(int i=list.levelnum; i>=0; i--)//printf("%d--->%d\n",i,list.num[i]);printf("---------------------\n");while(1){char cmd[10];int data;scanf("%s",cmd);if(!strcmp(cmd,"insert")||!strcmp(cmd,"i")){scanf("%d",&data);insert(data);}else if(!strcmp(cmd,"remove")||!strcmp(cmd,"r")){scanf("%d",&data);remove(data);}else if(!strcmp(cmd,"find")||!strcmp(cmd,"f")){scanf("%d",&data);if(find(data)){printf("success\n");}else{printf("failed\n");}}else if(!strcmp(cmd,"print")||!strcmp(cmd,"p")){printlist();}else if(!strcmp(cmd,"quit")||!strcmp(cmd,"q")){break;}elseprintf("command %s is not valid!\n",cmd);}return 0;}
收获:
1. next[1] 结构发在struct的后面,可以任意长数组,(动态申请一个next为max的Node,sizeof(Node)+(max-1)*sizeof(Node*))
typedef struct _Node{T data;struct _Node *next[1]; /*next[i] point to the next node in level i*/}Node;
2. remove()中,对x=x->next[0]这个地方,花了我半个小时找问题,,原来,如果如果没有这句,x就是保存的前面的Node而x->next[0]在后面被改变了,在调用就指向了错误的地方!!!
总之,就是【指针指向的地方在后面被改变了】,这个要小心,常常注意不到!!!!
0 0
- An implementation of Skip list
- An implementation of the skip list data structure written in C++
- An overview of Openvswitch implementation
- An overview of Openvswitch implementation
- An overview of Openvswitch implementation
- an issue of sctp sctp_getladdrs implementation
- An Implementation of Merge Sort in C
- 【基础知识】An Implementation of Double-Array Trie
- An Implementation of Double-Array Trie
- An Implementation of Double-Array Trie
- An Implementation of Double-Array Trie
- Implementation of linked list in C
- Implementation of carsten steger “An Unbiased Detector of Curvilinear Structures"
- skip list
- skip list
- Skip List
- Skip list
- Skip List
- VS2010+WIN7 配置驱动开发环境(wdk7.60)
- Windows中的进程通信
- spring源码学习之路---IOC初探
- ORACE_体系结构001_进程体系结构
- SSL协议体系结构
- An implementation of Skip list
- OpenMP学习(一)
- 怎样看文献
- How to bypass the WinSxS for CRT/MFC/ATL DLLs
- Windows中多线程的同步
- 3B再战:360又一次挟持了用户
- SQLite 的加密解密(开放宏定义)
- 3B大战 GS很受伤
- 3B大战 两败俱伤