skiplist

来源:互联网 发布:淘宝旺旺链接 编辑:程序博客网 时间:2024/06/06 12:53

数据量较大(百万级), 且要求部分有序(类似堆)或者全有序, 支持插入和删除。

list 查找慢, 导致插入和删除慢

vector查找快, 但是插入和删除消耗大,会移动近半元素

set/map,与 skiplist性能同级别。 但是实现复杂。


skiplist 在redis中作为set的底层容器。 插入、查找、删除级别都是log(n)


//author: lovelychen_1005@163.com/*改动:0 改为c++类。1 支持模板。 只是用简单类型测试过。 复杂类型未测试, 需要提供std::less<Key>2 支持遍历。 方式是Peek取得头部; 如果需要删掉,Delete掉Peek的返回值即可*/#pragma once#include <stdlib.h>#include <stdio.h>//http://www.cnblogs.com/liuhao/archive/2012/07/26/2610218.html//http://in.sdo.com/?p=711#define SKIPLIST_MAXLEVEL 25 template <typename Key> class SkipListNode;template <typename Key> class SkipListLevel;template <typename Key> class SkipListLevel {public:SkipListNode<Key> *forward;};template <typename Key> class SkipListNode {SkipListNode();~SkipListNode();public:Key score;SkipListNode *backward;SkipListLevel<Key> level[];void Free(){::free(this);}static SkipListNode *CreateNode(int level, const Key & score) {SkipListNode * sn = (SkipListNode *)(malloc(sizeof(*sn) + level*sizeof(SkipListLevel<Key>)));sn->score = score;return sn;}};template <typename Key> class SkipList {SkipList();~SkipList();public:SkipListNode<Key> *header, *tail;unsigned long length;int level;static SkipList *CreateList(void) {int j;SkipList *sl;sl = (SkipList *)(malloc(sizeof(*sl)));sl->level = 1;sl->length = 0;sl->header = SkipListNode<Key>::CreateNode(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 Free() {SkipListNode<Key> *node = this->header->level[0].forward, *next;free(this->header);while(node) {next = node->level[0].forward;node->Free();node = next;}free(this);}const Key &Peek(){const static Key nullKey(0);if(length <= 0) return nullKey;SkipListNode<Key>  *node = NULL;for (int i = this->level - 1; i >= 0; i--) {if (this->header->level[i].forward) {node = this->header->level[i].forward; break;}}return header->level[0].forward->score;}static int RandomLevel(void) {int level = 1;while((rand()&0xFFFF) < (0.5 * 0xFFFF)) level += 1;return (level < SKIPLIST_MAXLEVEL) ? level : SKIPLIST_MAXLEVEL;}SkipListNode<Key> *Insert(const Key & score) {SkipListNode<Key> *update[SKIPLIST_MAXLEVEL];SkipListNode<Key> *node;node = this->header;int i, level;for ( i = this->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 = RandomLevel();if (level > this->level) {for (i = this->level; i< level ;i++) {update[i] = this->header;}this->level = level;}node = SkipListNode<Key>::CreateNode(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] == this->header? NULL : update[0]);if (node->level[0].forward)node->level[0].forward->backward = node;elsethis->tail = node;this->length++;return node;}int Delete(const Key &score) {SkipListNode<Key> *update[SKIPLIST_MAXLEVEL], *node;int i;node = this->header;for(i = this->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) {DeleteNode(node, update);node->Free();return 1;} else {return 0;}return 0;}int Search(const Key & score) {SkipListNode<Key> *node;int i;node = this->header;for (i = this->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 Print() {SkipListNode<Key> *node;int i;for (i = 0; i < SKIPLIST_MAXLEVEL; i++) {printf("LEVEL[%d]: ", i);node = this->header->level[i].forward;while(node) {printf("%d -> ", (int)(node->score));node = node->level[i].forward;}printf("NULL\n");}}private:void DeleteNode(SkipListNode<Key> *x, SkipListNode<Key> **update){int i;for (i = 0; i < this->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 {this->tail = x->backward;}while (this->level > 1 && this->header->level[this->level-1].forward == NULL) this->level--;this->length--;}};


0 0
原创粉丝点击