SkipList跳表的实现
来源:互联网 发布:淘宝网婴幼儿童车 编辑:程序博客网 时间:2024/05/21 15:39
关键的是要理解Node结构中使用的柔性数组(代码的55行)。
/************************************************************************* > File Name: skiplist.cpp > Author: Summer > Mail: 745189913@qq.com > Created Time: Mon 25 Jul 2016 03:19:38 PM CST ************************************************************************/#include <iostream>#include <stdio.h>#include <stdlib.h>#include <assert.h>using namespace std;template<class KEY_TYPE, class VAL_TYPE>class CSkipList{private: struct Node;public: CSkipList(unsigned int uiMaxLevel); ~CSkipList(); bool Insert(KEY_TYPE key, VAL_TYPE value); bool Erase(KEY_TYPE key); VAL_TYPE* Search(KEY_TYPE key);public: class Iterator { public: explicit Iterator(const CSkipList* list); const KEY_TYPE& Key() const; VAL_TYPE* Value() const; bool Next(); bool IsEnd() const; private: const CSkipList *m_poList; struct Node* m_pstNode; };private: struct Node *NewNode(int iLevel); unsigned int RandomLevel();private: unsigned int m_uiMaxLevel; unsigned int m_uiLevel; Node *m_pstHead;};template<class KEY_TYPE, class VAL_TYPE>struct CSkipList<KEY_TYPE, VAL_TYPE>::Node{ KEY_TYPE key; VAL_TYPE value; Node* next[1]; // Flexible Array};template<class KEY_TYPE, class VAL_TYPE>CSkipList<KEY_TYPE, VAL_TYPE>::CSkipList(unsigned int uiMaxLevel){ m_uiMaxLevel = uiMaxLevel > 0 ? uiMaxLevel : 2; m_uiLevel = 0; m_pstHead = NewNode(m_uiMaxLevel - 1); assert(m_pstHead); for (unsigned i = 0; i < uiMaxLevel; ++i) { m_pstHead->next[i] = NULL; }}template<class KEY_TYPE, class VAL_TYPE>CSkipList<KEY_TYPE, VAL_TYPE>::~CSkipList(){ Node *p = m_pstHead; Node *next = NULL; while(p) { next = p->next[0]; free(p); p = next; }}template<class KEY_TYPE, class VAL_TYPE>typename CSkipList<KEY_TYPE, VAL_TYPE>::Node* CSkipList<KEY_TYPE, VAL_TYPE>::NewNode(int iLevel){ Node *p = (Node*)malloc(sizeof(Node) + iLevel*sizeof(Node*)); return p;}template<class KEY_TYPE, class VAL_TYPE>unsigned int CSkipList<KEY_TYPE, VAL_TYPE>::RandomLevel(){ unsigned int uiLevel = 1; while(rand()%2) { ++uiLevel; } uiLevel = uiLevel > m_uiMaxLevel ? m_uiMaxLevel : uiLevel; return uiLevel;}template<class KEY_TYPE, class VAL_TYPE>bool CSkipList<KEY_TYPE, VAL_TYPE>::Insert(KEY_TYPE key, VAL_TYPE value){ Node *p = NULL, *q = NULL; Node *update[m_uiMaxLevel]; p = m_pstHead; int i = m_uiLevel; for (; i >= 0; --i) { while((q=p->next[i]) && q->key < key) { p = q; } update[i] = p; } if (q && q->key == key) { q->value = value; return true; } unsigned int uiLevel = RandomLevel(); if (uiLevel > m_uiLevel) { for (i = m_uiLevel; i < uiLevel; ++i) { update[i] = m_pstHead; } m_uiLevel = uiLevel; } q = NewNode(uiLevel); if (NULL == q) { return false; } q->key = key; q->value = value; for (i = uiLevel - 1; i >= 0; --i) { q->next[i] = update[i]->next[i]; update[i]->next[i] = q; } return true;}template<class KEY_TYPE, class VAL_TYPE>bool CSkipList<KEY_TYPE, VAL_TYPE>::Erase(KEY_TYPE key){ Node *update[m_uiMaxLevel]; Node *q = NULL, *p = m_pstHead; int i = m_uiLevel; for (; i >= 0; --i) { while((q=p->next[i]) && q->key < key) { p = q; } update[i] = p; } if (!q || q->key != key) { return false; } for (i = m_uiLevel; i >= 0; --i) { if (update[i]->next[i] == q) { update[i]->next[i] = q->next[i]; if (m_pstHead->next[i] == NULL) { --m_uiLevel; } } } free(q); q = NULL; return true;}template<class KEY_TYPE, class VAL_TYPE>VAL_TYPE* CSkipList<KEY_TYPE, VAL_TYPE>::Search(KEY_TYPE key){ Node *q = NULL; Node *p = m_pstHead; int i = m_uiLevel; for (; i >= 0; --i) { while((q=p->next[i]) && q->key < key) { p =q; } if (q && key == q->key) { return &(q->value); } } return NULL;}template<class KEY_TYPE, class VAL_TYPE>inline CSkipList<KEY_TYPE,VAL_TYPE>::Iterator::Iterator(const CSkipList* list){ m_poList = list; assert(list); m_pstNode = list->m_pstHead;}template<class KEY_TYPE, class VAL_TYPE>inline const KEY_TYPE& CSkipList<KEY_TYPE, VAL_TYPE>::Iterator::Key() const{ assert(m_pstNode); return m_pstNode->key;}template<class KEY_TYPE, class VAL_TYPE>inline VAL_TYPE* CSkipList<KEY_TYPE, VAL_TYPE>::Iterator::Value() const{ assert(m_pstNode); return &(m_pstNode->value);}template<class KEY_TYPE, class VAL_TYPE>inline bool CSkipList<KEY_TYPE, VAL_TYPE>::Iterator::IsEnd() const{ return NULL == m_pstNode;}template<class KEY_TYPE, class VAL_TYPE>inline bool CSkipList<KEY_TYPE, VAL_TYPE>::Iterator::Next(){ if (NULL == m_pstNode || NULL == m_pstNode->next[0]) { return false; } m_pstNode = m_pstNode->next[0]; return true;}int main(int argc, char *argv[]){ int iMaxLevel = 5; int iEntry = 10; CSkipList<int, int> sl(5); srand(time(0)); cout << "test insert: " << sl.Insert(10 , 11) << endl; cout << "test search: " << *(sl.Search(10)) << endl; cout << "test erase: " << sl.Erase(10) << endl; cout << "test search after erase: " << (sl.Search(10) ? "Found" : "Not Found") << endl; for (int i = 0; i < iEntry; ++i) { int e = rand() % iEntry; cout << e << endl; sl.Insert(e, e + 1); } CSkipList<int, int>::Iterator it(&sl); while (it.Next()) { cout << "key=" << it.Key() << ", value=" << *(it.Value()) << endl; } return 0;}
参考资料:
http://www.ezlippi.com/blog/2014/12/skip-list.html
0 0
- SkipList跳表的实现
- SkipList跳表的原理与实现
- SkipList的java实现
- skiplist 跳表详解及其编程实现
- Go语言实现跳表(SkipList)
- skiplist 跳表详解及其编程实现
- C语言跳表(skiplist)实现
- skiplist 跳表详解及其编程实现
- skiplist 跳表详解及其编程实现
- SkipList跳表基本原理
- SkipList跳表基本原理
- SkipList跳表基本原理
- SkipList跳表基本原理
- SkipList跳表基本原理
- SkipList跳表基本原理
- SkipList 跳表学习
- skiplist 跳表详解及其编程实现--跳跃链表
- SkipList 跳表基本原理与实现(转载)
- 基础函数
- hdu 2089 不要62(数位DP/暴力)
- JStry&catch
- C语言:用异或^实现数据加密
- kuangbin——线段树专题 E - Just a Hook
- SkipList跳表的实现
- 弹幕效果实现
- HDU 5793 A Boring Question(快速幂+求逆元)
- OJ3311数据结构实验之串三:KMP应用
- 面试中关于key/value的问题及map的理解
- leetcode_c++: Regular Expression Matching(010)
- 从Windows到Linux(二)
- js函数
- node-webkit js 复制粘贴