SKIP LISTS,跳表算法和实现

解释的最详细的是原始的论文, Skip Lists: A Probabilistic Alternative to Balanced Trees

什么是跳表:

    Skip lists are a data structure that can be used in place of balanced trees. Skip lists use probabilistic balancing rather than strictly enforced balancing and as a result the algorithms for insertion and deletion in skip lists are much simpler and significantly faster than equivalent algorithms for balanced trees.

要讲明白跳表,不是一件容易的事,还是GOOGLE那篇论文吧······

之前看nessDB的实现,skipnode怎么也想象不出来如何关联联系,看这篇论文中下面两个图的时候,就明白了,花的太好了。

SKIP LISTS,跳表算法和实现 - liuzhaomin - 机敏,Strong

SKIP LISTS,跳表算法和实现 - liuzhaomin - 机敏,Strong

跳表完整实现:

#define MAXLEVEL (15)

typedef enum {ADD,DEL} OPT;

struct skipnode{
uint64_t val;
unsigned opt:24;

char key[NESSDB_MAX_KEY_SIZE];
struct skipnode *forward[1];
struct skipnode *next;
};

struct skiplist{
int count;
int size;
int level;

char pool_embedded[1024];
struct skipnode *hdr;
struct pool *pool;
};
struct skiplist *skiplist_new(size_t size)
{
int i;
struct skiplist *list = calloc(1, sizeof(struct skiplist));

// MAXLEVEL=15,hdr中有15+2=18个skipnode指针
list->hdr = malloc(sizeof(struct skipnode) + MAXLEVEL*sizeof(struct skipnode *));

for (i = 0; i <= MAXLEVEL; i++)
list->hdr->forward[i] = NIL;

list->size = size;
list->pool = (struct pool *) list->pool_embedded;

return list;
}


int skiplist_insert(struct skiplist *list, char *key, uint64_t val, OPT opt)
{
int i, new_level;
struct skipnode *update[MAXLEVEL+1];
struct skipnode *x;

if (!skiplist_notfull(list))
return 0;

x = list->hdr;
for (i = list->level; i >= 0; i--) {
while (x->forward[i] != NIL
&& cmp_lt(x->forward[i]->key, key))
x = x->forward[i];
update[i] = x; // 更新节点的跳跃指针
}

x = x->forward[0];
if (x != NIL && cmp_eq(x->key, key)) {
x->val = val;
x->opt = opt;
return(1);
}

for (new_level = 0; rand() < RAND_MAX/2 && new_level < MAXLEVEL; new_level++);

if (new_level > list->level) {
for (i = list->level + 1; i <= new_level; i++)
update[i] = NIL;

list->level = new_level;
}

// 每个node的node指针个数为level+2个,最后一个没有使用
if ((x =_pool_alloc(list,sizeof(struct skipnode) + new_level*sizeof(struct skipnode *))) == 0)
__PANIC("Pool alloc error, maybe less memory");

memcpy(x->key, key, NESSDB_MAX_KEY_SIZE);
x->val = val;
x->opt = opt;

for (i = 0; i <= new_level; i++) {
x->forward[i] = update[i]->forward[i];
update[i]->forward[i] = x;
}
list->count++;

return(1);
}

int skiplist_insert_node(struct skiplist *list, struct skipnode *node)
{
return skiplist_insert(list, node->key, node->val, node->opt);
}

struct skipnode *skiplist_lookup(struct skiplist *list, char* data)
{
int i;
struct skipnode *x = list->hdr;

for (i = list->level; i >= 0; i--) {
while (x->forward[i] != NIL
&& cmp_lt(x->forward[i]->key, data))
x = x->forward[i];
}
x = x->forward[0];
if (x != NIL && cmp_eq(x->key, data))
return (x);

return NULL;
}
这段代码写的很完美

nessDB的作者们真的很强大~~~ 给他们发的邮件总会给回复,还给我指点方向~~~3q~~~

向他们学习!!!!!!

转载于:https://my.oschina.net/astute/blog/91985

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值