跳跃表

来源:互联网 发布:淘宝客关闭返利 编辑:程序博客网 时间:2024/05/16 17:59

跳跃表(skiplist)是非常优秀的数据结构,其插入,查询,删除的复杂度为O(logN),即使在最坏情况下为O(N),但最坏情况出现概率低。与skiplist的各种操作复杂度相当的数据结构还有大家熟知的AVL树,红黑树等,但跳跃表的实现比实现简单,想一想AVL树,红黑树的左旋右旋各种旋,不参考各种代码以及书籍不可能写出来。目前LevelDB的核心数据结构是用跳跃表实现的,redis的sorted set数据结构也是跳表实现的。


当我们使用链表存储有序数列时,查询操作的复杂度为O(N)。跳跃表是一种随机化的数据结构,能够有效解决有序链表查找特定值的困哪,其是典型的空间换时间。

构建有序链表:

构建跳跃表:



以下为redis的sorted set中关于跳跃表的代码:

skiplist.h

#ifndef __SKIPLIST_H#define __SKIPLIST_H#define SKIPLIST_MAXLEVEL 8 typedef struct skiplistNode {    double score;    struct skiplistNode *backward;//指向前继结点    struct skiplistLevel {        struct skiplistNode *forward;//记录该结点在每一层的后继结点    }level[];}skiplistNode;typedef struct skiplist {    struct skiplistNode *header, *tail;    unsigned long length;    int level;}skiplist;#endif

skiplist.c

#include "skiplist.h"#include <stdlib.h>#include <stdio.h>skiplistNode *slCreateNode(int level, double score) {    skiplistNode * sn = malloc(sizeof(*sn) + level*sizeof(struct skiplistLevel));    sn->score = score;    return sn;}skiplist *slCreate(void) {    int j;    skiplist *sl;    sl = malloc(sizeof(*sl));    sl->level = 1;    sl->length = 0;    sl->header = slCreateNode(SKIPLIST_MAXLEVEL, 0);    for(j = 0; j < SKIPLIST_MAXLEVEL; j++) {        sl->header->level[j].forward = NULL;    }    sl->header->backward = NULL;    sl->tail = NULL;    return sl;}void slFreeNode(skiplistNode *sn) {    free(sn);}void slFree(skiplist *sl) {    skiplistNode *node = sl->header->level[0].forward, *next;    free(sl->header);    while(node) {        next = node->level[0].forward;        slFreeNode(node);        node = next;    }    free(sl);}int slRandomLevel(void) {//加入随机性,计算插入值应该是在第几层    int level = 1;    while((rand()&0xFFFF) < (0.5 * 0xFFFF))         level += 1;    return (level < SKIPLIST_MAXLEVEL) ? level : SKIPLIST_MAXLEVEL;}skiplistNode *slInsert(skiplist *sl, double score) {    skiplistNode *update[SKIPLIST_MAXLEVEL];    skiplistNode *node;    node = sl->header;    int i, level;    for ( i = sl->level-1; i >= 0; i--) {        while(node->level[i].forward && node->level[i].forward->score < score) {            node = node->level[i].forward;        }        update[i] = node;    }    level = slRandomLevel();    if (level > sl->level) {        for (i = sl->level; i< level ;i++) {            update[i] = sl->header;        }        sl->level = level;    }    node = slCreateNode(level, score);    for (i = 0; i < level; i++) {        node->level[i].forward = update[i]->level[i].forward;        update[i]->level[i].forward = node;    }    node->backward = (update[0] == sl->header? NULL : update[0]);    if (node->level[0].forward)        node->level[0].forward->backward = node;    else        sl->tail = node;    sl->length++;    return node;}void slDeleteNode(skiplist *sl, skiplistNode *x, skiplistNode **update){    int i;    for (i = 0; i < sl->level; i++) {        if (update[i]->level[i].forward == x) {            update[i]->level[i].forward = x->level[i].forward;        }    }    if (x->level[0].forward) {        x->level[0].forward->backward = x->backward;    } else {        sl->tail = x->backward;    }    while (sl->level > 1 && sl->header->level[sl->level-1].forward == NULL)         sl->level--;    sl->length--;}int slDelete(skiplist *sl, double score) {    skiplistNode *update[SKIPLIST_MAXLEVEL], *node;    int i;    node = sl->header;    for(i = sl->level-1; i >= 0; i--) {        while (node->level[i].forward && node->level[i].forward->score < score) {            node = node->level[i].forward;        }        update[i] = node;    }    node = node->level[0].forward;    if (node && score == node->score) {        slDeleteNode(sl, node, update);        slFreeNode(node);        return 1;    } else {        return 0;    }    return 0;}int slSearch(skiplist *sl, double score) {    skiplistNode *node;    int i;    node = sl->header;    for (i = sl->level-1; i >= 0 ;i--) {        while(node->level[i].forward && node->level[i].forward->score < score) {            node = node->level[i].forward;        }    }    node = node->level[0].forward;    if (node && score == node->score) {        printf("Found %d\n",(int)node->score);        return 1;    } else {        printf("Not found %d\n", (int)score);        return 0;    }}void slPrint(skiplist *sl) {    skiplistNode *node;    int i;    for (i = 0; i < SKIPLIST_MAXLEVEL; i++) {        printf("LEVEL[%d]: ", i);        node = sl->header->level[i].forward;        while(node) {            printf("%d -> ", (int)(node->score));            node = node->level[i].forward;        }        printf("NULL\n");    }}#ifdef SKIP_LIST_TEST_MAINint main() {    srand((unsigned)time(0));    int count = 20, i;    printf("### Function Test ###\n");    printf("=== Init Skip List ===\n");    skiplist * sl = slCreate();    for ( i = 0; i < count; i++) {        slInsert(sl,i);    }    printf("=== Print Skip List ===\n");    slPrint(sl);    printf("=== Search Skip List ===\n");    for (i = 0; i < count; i++) {        int value = rand()%(count+10);        slSearch(sl, value);    }    printf("=== Delete Skip List ===\n");    for (i = 0; i < count+10; i+=2) {        printf("Delete[%d]: %s\n", i, slDelete(sl, i)?"SUCCESS":"NOT FOUND");    }    slPrint(sl);    slFree(sl);    sl = NULL;}#endif

测试结果:

### Function Test ###=== Init Skip List ====== Print Skip List ===LEVEL[0]: 0 -> 1 -> 2 -> 3 -> 4 -> 5 -> 6 -> 7 -> 8 -> 9 -> 10 -> 11 -> 12 -> 13 -> 14 -> 15 -> 16 -> 17 -> 18 -> 19 -> NULLLEVEL[1]: 0 -> 2 -> 4 -> 7 -> 9 -> 10 -> 11 -> 12 -> 14 -> 15 -> 17 -> 18 -> NULLLEVEL[2]: 7 -> 10 -> 12 -> 14 -> 15 -> NULLLEVEL[3]: 10 -> 14 -> 15 -> NULLLEVEL[4]: 10 -> 14 -> NULLLEVEL[5]: NULLLEVEL[6]: NULLLEVEL[7]: NULL=== Search Skip List ===Found 1Found 18Not found 21Not found 24Found 10Not found 20Found 14Found 10Found 19Found 18Not found 27Found 5Found 0Found 0Found 18Not found 26Found 13Not found 28Not found 29Not found 23=== Delete Skip List ===Delete[0]: SUCCESSDelete[2]: SUCCESSDelete[4]: SUCCESSDelete[6]: SUCCESSDelete[8]: SUCCESSDelete[10]: SUCCESSDelete[12]: SUCCESSDelete[14]: SUCCESSDelete[16]: SUCCESSDelete[18]: SUCCESSDelete[20]: NOT FOUNDDelete[22]: NOT FOUNDDelete[24]: NOT FOUNDDelete[26]: NOT FOUNDDelete[28]: NOT FOUNDLEVEL[0]: 1 -> 3 -> 5 -> 7 -> 9 -> 11 -> 13 -> 15 -> 17 -> 19 -> NULLLEVEL[1]: 7 -> 9 -> 11 -> 15 -> 17 -> NULLLEVEL[2]: 7 -> 15 -> NULLLEVEL[3]: 15 -> NULLLEVEL[4]: NULLLEVEL[5]: NULLLEVEL[6]: NULLLEVEL[7]: NULL


0 0
原创粉丝点击