#ifndef MY_SKIP_LIST #define MY_SKIP_LIST #include <stdlib.h> #include <stdio.h> #include <limits.h> typedef int DataType; #define MAX_LEVEL 8 struct DataNode; typedef struct NodeLevel { struct DataNode * forward; unsigned span; }NodeLevel,*PNodeLevel; /** data node which stores data with DataType */ typedef struct DataNode { // int (*compare)(DataType val1,DataType val2); DataType value; unsigned level_size; NodeLevel level[]; }DataNode,*PDataNode; /** skip list struct */ typedef struct SkipList { unsigned level; unsigned size; PDataNode header; }SkipList,*PSkipList; /** *get rand level for data node created */ unsigned rand_level(); /** *initialize an empty skiplist */ PSkipList skiplist_init(); /** *destory a skip list 'sl',and free the memory occupied. */ void destory_skiplist(PSkipList *sl); /** *make a new skip list node which stores 'val', *returns a pointer to the data node newly made */ PDataNode make_node(DataType val,unsigned level); /** *delete a data node with data 'val' from skip list 'sl', *returns a pointer of DataNode deleted, *if DataNode with data 'val' does not exist,return NULL *note:memory occupied by 'val' not freed */ PDataNode del(PSkipList sl,DataType val); /** *add a data node with data 'val' from skip list 'sl', *returns a pointer of DataNode added, *note:memory occupied by 'val' not freed */ PDataNode add(PSkipList sl,DataType val); /** *find 'val' in skiplist 'sl',if founed,return the pointer of node with value 'val' *if not return NULL */ PDataNode find(PSkipList sl,DataType val); /** *free the memory occupied by 'node' */ void free_node(PDataNode node); void print_skiplist(PSkipList sl); void print_level(PSkipList sl, int i); #endif // MY_SKIP_LIST
#include "skiplist.h" unsigned rand_level() { int level = 1; while(rand()%2 && level <= MAX_LEVEL) level++; return level; } PDataNode make_node(DataType val,unsigned level) { PDataNode node = (PDataNode)malloc(sizeof(DataNode) + sizeof(NodeLevel)*level); if(node == NULL) return NULL; node->value = val; node->level_size = level; int i = 0; for(i=0; i<level; i++) { node->level[i].forward = NULL; node->level[i].span = 0; } return node; } void free_node(PDataNode node) { if(NULL == node) return; free(node); } PSkipList skiplist_init() { PSkipList sl = NULL; sl = (PSkipList)malloc(sizeof(SkipList)); sl->level = 1; sl->size = 0; PDataNode header = make_node(INT_MIN,MAX_LEVEL); if(header == NULL) { free(sl); return NULL; } sl->header = header; return sl; } void destory_skiplist(PSkipList *sl) { if(*sl == NULL) return; PDataNode pNode = (*sl)->header->level[0].forward; PDataNode next = NULL; while(pNode) { next = pNode->level[0].forward; free_node(pNode); pNode = next; } pNode = NULL; next = NULL; free_node((*sl)->header); (*sl)->header = NULL; free(*sl); (*sl) = NULL; return; } PDataNode del(PSkipList sl,DataType val) { if(sl == NULL) return NULL; PDataNode del_node = NULL; PNodeLevel update[MAX_LEVEL]; int i = MAX_LEVEL - 1; PDataNode cur,pre; pre = sl->header; cur = pre; while(i >= 0) { cur = pre->level[i].forward; while(cur != NULL && cur->value < val) { pre = cur; cur = cur->level[i].forward; } if(cur != NULL && cur->value == val) { del_node = cur; } update[i] = &(pre->level[i]); i--; } if(del_node == NULL) return NULL; i = MAX_LEVEL - 1; while(i >= 0) { if(update[i]->forward == NULL) { i--; continue; } else if(update[i]->forward->value > val) { update[i]->span--; i--; } else { update[i]->forward = del_node->level[i].forward; if(del_node->level[i].forward == NULL) update[i]->span = 0; else update[i]->span += del_node->level[i].span - 1; i--; } } sl->size--; return del_node; } PDataNode add(PSkipList sl,DataType val) { if(sl == NULL) return NULL; unsigned node_level = rand_level(); PDataNode pNode = make_node(val,node_level); printf("Level:%d value:%d\n",node_level,val); if(pNode == NULL) return NULL; PNodeLevel update[MAX_LEVEL]; //查找插入位置的遍历路径上处于第i层的节点在链表中的排位,头节点为rank[MAX_LEVEL-1]=0 //查找从最高层开始且头节点在链表中是第一个,所以rank[MAX_LEVEL-1]=0 unsigned rank[MAX_LEVEL] = {0}; int i = MAX_LEVEL-1; PDataNode cur,pre; pre = sl->header; cur = pre; while(i >= 0) { rank[i] = (i == MAX_LEVEL-1 ? 0 : rank[i+1]); cur = pre->level[i].forward; while(cur && cur->value < val) { rank[i] += pre->level[i].span; pre = cur; cur = cur->level[i].forward; } if(cur && cur->value == val) return NULL; update[i] = &(pre->level[i]); i--; } i = MAX_LEVEL-1; for(;i >=0; i--) { if(update[i]->forward == NULL && i > node_level-1) { continue; } else if(update[i]->forward == NULL && i <= node_level-1) { update[i]->forward = pNode; //节点的插入位置一定是在查找路基上第0层节点的后面一个 //rank[0] - rank[i]得到的是查找路径上要更新的第层节点距离第0层节点的距离跨度, //这个跨度+1就得到了更新路劲上第i层节点到插入节点的跨度 update[i]->span = (rank[0] - rank[i]) + 1; } else if(update[i]->forward && i > node_level-1) { update[i]->span++; } else { pNode->level[i].forward = update[i]->forward; //pNode->level[i].span = (update[i]->span + 1) - ((rank[0] - rank[i]) + 1); pNode->level[i].span = update[i]->span - (rank[0] - rank[i]); update[i]->forward = pNode; update[i]->span = (rank[0] - rank[i]) + 1; } } sl->size++; return pNode; } PDataNode find(PSkipList sl,DataType val) { if(sl == NULL) return NULL; PDataNode pre = sl->header; PDataNode cur = pre; int i = MAX_LEVEL-1; unsigned rank[MAX_LEVEL-1] = {0}; while(i >= 0) { rank[i] = (i == MAX_LEVEL-1 ? 0 : rank[i+1]); cur = pre->level[i].forward; while(cur != NULL && cur->value < val) { rank[i] += pre->level[i].span; pre = cur; cur = cur->level[i].forward; } if(cur != NULL && cur->value == val) { printf("val=%d,rank:%u\n",val,rank[i]+1); return cur; } i--; } return NULL; } void print_level(PSkipList sl, int i) { PDataNode pNode = sl->header; printf("level %d ",i); while(pNode) { printf("%d",pNode->value); int num = pNode->level[i].span; while(num > 0) { printf("-"); num--; } pNode = pNode->level[i].forward; } printf("\n"); } void print_skiplist(PSkipList sl) { if(sl == NULL) { printf("Null list"); return ; } int i = MAX_LEVEL - 1; while(i >= 0) { print_level(sl,i); i--; } }
#include <stdio.h> #include <stdlib.h> #include "skiplist.h" int main() { PSkipList sl = skiplist_init(); DataType vals[] = {1,3,5,7,9,2,4,6,8,10,11,15,12,18,21,31,56,100,94,68,60,88,66}; unsigned val_size = sizeof(vals)/sizeof(vals[0]); printf("value number = %u\n",val_size); unsigned i = 0; for(;i < val_size; i++) { add(sl,vals[i]); } print_skiplist(sl); find(sl,31); find(sl,100); find(sl,66); PDataNode del_node = del(sl,31); free_node(del_node); print_skiplist(sl); del_node = del(sl,88); free_node(del_node); print_skiplist(sl); del_node = del(sl,21); free_node(del_node); print_skiplist(sl); del_node = del(sl,6); free_node(del_node); print_skiplist(sl); del_node = del(sl,94); free_node(del_node); print_skiplist(sl); del_node = del(sl,60); free_node(del_node); print_skiplist(sl); del_node = del(sl,68); free_node(del_node); print_skiplist(sl); del_node = del(sl,100); free_node(del_node); print_skiplist(sl); del_node = del(sl,1); free_node(del_node); print_skiplist(sl); del_node = NULL; destory_skiplist(&sl); print_skiplist(sl); return 0; }