SkipList跳表C++实现

来源:互联网 发布:海淘软件 编辑:程序博客网 时间:2024/05/16 01:43

跳跃列表(也称跳表)是一种随机化数据结构,基于并联的链表,利用空间换取各种操作的时间,其效率可比拟于一些平衡树

(对于大多数操作需要O(log n)平均时间),但更容易实现。详情见wiki。

下面是C++实现,有不对之处,望指出。

#ifndef SKIPLIST_H#define SKIPLIST_H#include <iostream>#include <random>  //c++11#include <cstdlib>template <typename Key,typename Type>struct SkipListNode{Key key;Type value;SkipListNode<Key,Type>* forward[1];};// Key and Type comparable template<typename Key,typename Type,int MaxLevel = 15>class SkipList{typedef SkipListNode<Key,Type>* pSkipListNode;void newNodeOfLevel(pSkipListNode& p,int level = 0){int size = sizeof(SkipListNode<Key,Type>) + level*sizeof(pSkipListNode);p = (pSkipListNode)malloc(size);}public:SkipList();~SkipList();bool insert(const Key& k,const Type& t);bool remove(const Key& k,Type& tout);bool search(const Key& k,Type& tout);void print();int getSize() { return size; }private:int randomLevel();int level;int size;pSkipListNode header;pSkipListNode NIL;};template<typename Key,typename Type,int MaxLevel>SkipList<Key,Type,MaxLevel>::SkipList():size(0),level(0){newNodeOfLevel(NIL);//set max key in NILNIL->key = 0x7fffffff;newNodeOfLevel(header,MaxLevel);for(int i = 0; i < MaxLevel; i++){header->forward[i] = NIL;}}template<typename Key,typename Type,int MaxLevel>SkipList<Key,Type,MaxLevel>::~SkipList(){pSkipListNode p = header;pSkipListNode q;while(p != NIL){q = p->forward[0];free(p);p = q;}free(p);  //NIL}template<typename Key,typename Type,int MaxLevel>int SkipList<Key,Type,MaxLevel>::randomLevel(){int lev = 0;std::random_device rd;while(1){if(rd()%2 == 0)  lev++;else  break;}return lev < MaxLevel ? lev : MaxLevel-1;}template<typename Key,typename Type,int MaxLevel>bool SkipList<Key,Type,MaxLevel>::insert(const Key& k,const Type& t){pSkipListNode update[MaxLevel], p = header;for(int i = level; i >= 0; i--){while(p->forward[i] != NIL && p->forward[i]->key < k)  p = p->forward[i];update[i] = p;}p = p->forward[0];if(p != NIL && p->key == k){p->value = t;return false;}int lev = randomLevel();if(lev > level){lev = ++level;update[lev] = header;}pSkipListNode newNode;newNodeOfLevel(newNode,lev);newNode->key = k;newNode->value = t;for(int i = lev; i >= 0; i--){p = update[i];newNode->forward[i] = p->forward[i];p->forward[i] = newNode;}++size;return true;}template<typename Key,typename Type,int MaxLevel>bool SkipList<Key,Type,MaxLevel>::remove(const Key& k,Type& tout){pSkipListNode update[MaxLevel], p = header;for(int i = level; i >= 0; i--){while(p->forward[i] != NIL && p->forward[i]->key < k)  p = p->forward[i];update[i] = p;}p = p->forward[0];if(p != NIL && p->key == k){tout = p->value;for(int i = 0; i <= level; i++){if(update[i]->forward[i] != p)break;update[i]->forward[i] = p->forward[i];}free(p);while(level > 0 && header->forward[level] == NIL)level--;size--;return true;}elsereturn false;}/*template<typename Key,typename Type,int MaxLevel = 15>bool SkipList::removeKey(Key& k){}*/template<typename Key,typename Type,int MaxLevel>bool SkipList<Key,Type,MaxLevel>::search(const Key& k,Type& tout){pSkipListNode p = header;for(int i = level; i >= 0; i--){while(p->forward[i] != NIL && p->forward[i]->key < k)  p = p->forward[i];}p = p->forward[0];if(p != NIL && k == p->key){tout = p->value;return true;}return false;}template<typename Key,typename Type,int MaxLevel>void SkipList<Key,Type,MaxLevel>::print(){pSkipListNode p = header;while(p->forward[0] != NIL){std::cout << "Key:" << p->forward[0]->key << "Value:" << p->forward[0]->value << std::endl;p = p->forward[0];}}#endif
测试数据(编译使用O2):

先执行随机插入1000个数据,再执行随机查找1000个数据,再删除1000个数据。

测试代码:

#include "SkipList.h"using namespace std;int main(){    SkipList<int,int,10>  t;    int num[1000];    std::random_device rd;    //insert    for(int i = 0; i < 1000; i++)    {        num[i] = rd() % 10000;        t.insert(num[i],num[i]);    }    //search    for(int i = 0; i < 1000; i++)    {        int res;        t.search(rd() % 10000,res);    }    //remove    for(int i = 0; i < 1000; i++)    {        int res;        t.remove(num[i],res);    }}
结果:

0 0
原创粉丝点击