跳表(SkipList)
来源:互联网 发布:阿里云建立二级域名 编辑:程序博客网 时间:2024/06/05 09:47
最近在看leveldb的源码,看到核心的skiplist时发现自己浑浑噩噩的,本来就不太懂,.h文件里还竟是模板迭代器啥的,于是决定还是先吧思路理清楚,都提倡不要重复发明轮子,但只有熟悉轮子的制作过程,用起来才可能得心应手啊。
这篇图文并茂的博文将跳表的基本操作描述的很不错:http://kenby.iteye.com/blog/1187303
为了便于忘了再看时能很快懂(源码真心不好看呀),下面的代码中很多地方都注释了一些我的理解
#include <cstdio>#include <cstdlib>#include <cstring>#define MAX_LEVEL10#define ALL_PART4struct SkipListNode{//dataint key;//level count the node appearsint height;//soft memberSkipListNode* next[1];};int RandomLevel(){int h = 1;while(rand() % ALL_PART == 0) ++h;return h;}SkipListNode* NewNode(int level){return reinterpret_cast<SkipListNode*>(malloc(sizeof(SkipListNode) + (level-1)*sizeof(SkipListNode*)));}void FreeNode(SkipListNode* p){free(p);p = NULL;}class SkipList{public:SkipList();~SkipList();bool Contain(int k)const;bool Insert(int k);bool Delete(int k);void Show()const;private:void findLastLessThan(int k, SkipListNode* arr[MAX_LEVEL])const;private:SkipListNode* head;};/*********************************** implementation *********************************/SkipList::SkipList(){head = NewNode(MAX_LEVEL);memset(head, 0, sizeof(SkipListNode) + (MAX_LEVEL-1)*sizeof(SkipListNode*));head->height = 1;}SkipList::~SkipList(){int i = 0, m = head->height;for(; i < m; ++i){//delete nodes with height iSkipListNode *p = head, *q = head->next[i];for(; q; q = p->next[i]){if(q->height == i+1){p->next[i] = q->next[i];FreeNode(q);}else p = q;}}FreeNode(head);}void SkipList::Show()const{puts("SkipList:");int m = head->height;for(; m; --m){printf("level %d: ", m-1);SkipListNode* p = head->next[m-1];bool first = true;for(; p; p = p->next[m-1]){if(first) first = false;else printf("-->");printf("%d", p->key);}puts("");}}void SkipList::findLastLessThan(int k, SkipListNode* arr[MAX_LEVEL])const{// puts("enter SkipList::findLastLessThan");SkipListNode *p = head, *q;int m = p->height;//find each level's last node whose key is smaller than kfor(int i = m-1; i >= 0; --i){//move horizontally for level iwhile((q = p->next[i]) && q->key < k) p = q;//p is last node in level i that has key smaller than karr[i] = p;// printf("head = %p, arr[%d] = %p\n", head, i, p);}// puts("leave SkipList::findLastLessThan");}bool SkipList::Contain(int k)const{SkipListNode* update[MAX_LEVEL], *q;findLastLessThan(k, update);q = update[0]->next[0];return q && q->key == k;}bool SkipList::Insert(int k){SkipListNode* update[MAX_LEVEL], *q;findLastLessThan(k, update);q = update[0]->next[0];// printf("head = %p, q = %p\n", head, q);//q is the first node in level 0, whose key is no lesser than kif(q && q->key == k) return false;//k is not in skiplist yet, find its highest appearing levelint h = RandomLevel(), m = head->height;// printf("height for %d is %d\n", k, h);if(h > m){//we need to redirect update[m, h) to headfor(int i = m; i < h; ++i) update[i] = head;//need to change skiplist's whole heighthead->height = h;}//now insert k behind every update[0, h)SkipListNode* t = NewNode(h);t->key = k;t->height = h;for(int i = 0; i < h; ++i){t->next[i] = update[i]->next[i];update[i]->next[i] = t;}return true;}bool SkipList::Delete(int k){SkipListNode* update[MAX_LEVEL], *q;findLastLessThan(k, update);q = update[0]->next[0];//check k is in skip list or not, that is whether it appears in the lowest levelif(!q || q->key != k) return false;//update[] are k's previous nodes, redirect them to k's next onesfor(int i = q->height-1; i >= 0; --i){update[i]->next[i] = q->next[i];}FreeNode(q);//check if we need to change skiplist's whole heightint h = head->height;for(; h; --h){if(head->next[h-1]) break;}head->height = h;return true;}void test(){int cnt = 10, i;SkipList sl;puts("==== Insert ====");for(i = 0; i < cnt; ++i){if(sl.Insert(i)) printf("Insert %d into SkipList done\n", i);else printf("%d already in SkipList\n", i);if(sl.Insert(i)) printf("Insert %d into SkipList done\n", i);else printf("%d already in SkipList\n", i);}getchar();puts("==== Show ====");sl.Show();getchar();puts("==== Contain ====");for(i = 0; i < cnt; ++i){int v = rand() % (cnt + cnt / 2);if(sl.Contain(v)) printf("%d is in SkipList\n", v);else printf("%d is not in SkipList\n", v);}getchar();puts("==== Delete ====");for(i = cnt-1; i >= cnt/2; --i){if(sl.Delete(i)) printf("Delete %d from SkipList done\n", i);else printf("%d not in SkipList\n", i);if(sl.Delete(i)) printf("Delete %d from SkipList done\n", i);else printf("%d not in SkipList\n", i);}getchar();puts("==== Show ====");sl.Show();getchar();}int main(){test();puts("done");getchar();return 0;}
0 0
- skiplist 跳表(1)
- 跳表(SkipList)
- 跳表(Skiplist)
- 跳表(Skiplist)
- 扩展数据结构--跳表(SkipList)
- 跳表 SkipList(一)基本原理
- Java基础 - 跳表(SkipList)
- SkipList 跳表
- SkipList跳表
- 跳表SkipList
- SkipList 跳表
- SkipList 跳表
- 跳表SkipList
- SkipList 跳表
- SkipList 跳表
- SkipList 跳表
- SkipList 跳表
- SkipList 跳表
- Hduoj1017【水题】
- 动态规划-钢条切割《算法导论》
- 获取屏幕的大小
- EditText设置光标位置问题
- Java 集合 线程安全
- 跳表(SkipList)
- 如何借助加密软件预防企业内部泄密风险
- Vaadin——打开PDF文档
- java总结输入流输出流
- 数据结构实验:连通分量个数(并查集)
- 老鼠迷宫之《爱我别走》【内附代码和游戏下载地址】
- Leetcode 23 Merge k Sorted Lists
- Code Forces 558 C. Amr and Chemistry(数论+位运算)
- Android启动页面禁止退出 防止多次点击back键