simple skiplist implementation in c
来源:互联网 发布:数据库的类型有哪些 编辑:程序博客网 时间:2024/05/07 23:57
#ifndef MY_SKIP_LIST#define MY_SKIP_LIST#include <stdlib.h>#include <stdio.h>#include <limits.h>typedef int DataType;#define MAX_LEVEL 8struct 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;}
0 0
- simple skiplist implementation in c
- Reflection in C++: The simple implementation of Splinter Cell
- CRC Implementation Code in C
- CRC Implementation Code in C
- A Simple Implementation of Binary Search Tree in C++
- Matrix Factorization: A Simple Tutorial and Implementation in
- A simple implementation of string split in C++
- Matrix Factorization: A Simple Tutorial and Implementation in Python
- Matrix Factorization: A Simple Tutorial and Implementation in Python
- Matrix Factorization: A Simple Tutorial and Implementation in Python
- 两个用C实现遗传算法的程序 an example of a very simple genetic algorithm in C and a GA implementation using binary and real coded variables
- A Generic vector implementation in C
- An Implementation of Merge Sort in C
- Stack ---- Implementation in C and Python
- Implementation of linked list in C
- Simple Queue Impliment in C
- Simple Plug-in Architecture in Plain C
- Very simple A* algorithm implementation
- Extjs 随笔备忘
- Python如何获取JPG图片的长宽等信息
- Servlet之HTTP状态码
- BZOJ 1213 HNOI2004 高精度开根 二分+高(Py)精(thon)度
- checkStyle配置说明
- simple skiplist implementation in c
- Erlang入门:服务进程实例操作与练习1
- OpenStack之RPC调用(一)
- c++中list的使用说明
- 必须Mark!43个优秀的Swift开源项目推荐
- jQuery函数大全
- UVA 1160 X-Plosives
- 灰度图像--频域滤波 傅里叶变换之连续信号傅里叶变换(FT)
- Article Archives