#ifndef SKIPLIST_H_
#define SKIPLIST_H_
#include <ctime>
#include <cstdlib>
#include <iostream>
#include <fstream>
/* 简单跳跃表,它允许简单的插入和删除元素,并提供O(logn)的查询时间复杂度。 */
/*
SkipList_Int的性质
(1) 由很多层结构组成,level是通过一定的概率随机产生的,基本是50%的产生几率。
(2) 每一层都是一个有序的链表,默认是升序,每一层的链表头作为跳点。
(3) 最底层(Level 1)的链表包含所有元素。
(4) 如果一个元素出现在Level i 的链表中,则它在Level i 之下的链表也都会出现。
(5) 每个节点包含四个指针,但有可能为nullptr。
(6) 每一层链表横向为单向连接,纵向为双向连接。
*/
class RandomHeight {
public:
RandomHeight(int maxLvl, float prob) : max_lvl_(maxLvl), prob_(prob) {
srand(time(NULL));
}
~RandomHeight() {}
int newLevel() {
int tmpLvl = 1;
while ((rand()%2) < prob_ && tmpLvl < max_lvl_) {
tmpLvl++;
}
return tmpLvl;
}
private:
int max_lvl_;
float prob_;
};
struct Product {
float cost;
int quantity;
int location;
};
typedef Product productData;
template<class Key, class Obj>
class SkipList;
//SkipNode
template<class Key, class Obj>
class SkipNode {
public:
//用于构造带数据的结点
SkipNode(Key*, Obj*, int lvl);
//用于构造头尾结点
SkipNode(int lvl);
~SkipNode();
Key* getKey() { return key_; }
Obj* getObj() { return obj_; }
int getLevel() { return level_; }
SkipNode **fwd_nodes;
private:
Key* key_;
Obj* obj_;
int level_;
};
template<class Key, class Obj>
SkipNode<Key, Obj>::SkipNode(Key *key, Obj* obj, int lvl)
: key_(key), obj_(obj), level_(lvl) {
fwd_nodes = new SkipNode<Key, Obj>* [lvl+1];
for (int i=1; i<=level_; i++)
fwd_nodes[i] = (SkipNode<Key, Obj>*)NULL;
}
template<class Key, class Obj>
SkipNode<Key, Obj>::SkipNode(int lvl)
: key_(NULL), obj_(NULL), level_(lvl) {
fwd_nodes = new SkipNode<Key, Obj>* [lvl+1];
for (int i=1; i<=level_; i++)
fwd_nodes[i] = (SkipNode<Key, Obj>*)NULL;
}
template<class Key, class Obj>
SkipNode<Key, Obj>::~SkipNode() {
delete key_;
delete obj_;
delete[] fwd_nodes;
}
//SkipList
template<class Key, class Obj>
class SkipList {
public:
SkipList(float prob, int maxLvl, Key* maxKey);
~SkipList();
bool insert(Key*, Obj*);
bool remove(Key*);
Obj* retrieve(Key*);
void dump(std::ofstream &);
private:
SkipNode<Key, Obj>* head_;
SkipNode<Key, Obj>* tail_;
float prob_;
int max_level_;
int cur_level_;
RandomHeight *rand_gen_;
};
template<class Key, class Obj>
SkipList<Key, Obj>::SkipList(float prob, int maxLvl, Key* maxKey)
: prob_(prob), max_level_(maxLvl), cur_level_(1) {
rand_gen_ = new RandomHeight(max_level_, prob_);
head_ = new SkipNode<Key, Obj>(max_level_);
tail_ = new SkipNode<Key, Obj>(maxKey, NULL, max_level_);
for (int x=1; x<=max_level_; x++)
head_->fwd_nodes[x] = tail_;
}
template<class Key, class Obj>
SkipList<Key, Obj>::~SkipList() {
SkipNode<Key, Obj>* tmp;
SkipNode<Key, Obj>* nxt;
tmp = head_;
while (tmp) {
nxt = tmp->fwd_nodes[1];
delete tmp;
tmp = nxt;
}
}
template<class Key, class Obj>
bool SkipList<Key, Obj>::insert(Key* k, Obj *o) {
int lvl = 0, h = 0;
SkipNode<Key, Obj>** updateVec = new SkipNode<Key, Obj>* [max_level_+1];
SkipNode<Key, Obj>* tmp = head_;
Key* cmpKey = NULL;
//updateVec保存每一层插入结点的前一个结点
for (h = cur_level_; h >= 1; h--) {
cmpKey = tmp->fwd_nodes[h]->getKey();
while (*cmpKey < *k) {
tmp = tmp->fwd_nodes[h];
cmpKey = tmp->fwd_nodes[h]->getKey();
}
updateVec[h] = tmp;
}
//最底层的后续一个结点
tmp = tmp->fwd_nodes[1];
cmpKey = tmp->getKey();
if (*cmpKey == *k) {
//If dup, return false
return false;
}
else {
lvl = rand_gen_->newLevel();
if (lvl > cur_level_) {
for (int i=cur_level_+1; i<=max_level_; i++)
updateVec[i] = head_;
cur_level_ = lvl;
}
//insert new element
tmp = new SkipNode<Key, Obj>(k, o, lvl);
for (int i=1; i<=lvl; i++) {
tmp->fwd_nodes[i] = updateVec[i]->fwd_nodes[i];
updateVec[i]->fwd_nodes[i] = tmp;
}
}
return true;
}
template<class Key, class Obj>
bool SkipList<Key, Obj>::remove(Key* k) {
int h = 0;
SkipNode<Key, Obj>** updateVec = new SkipNode<Key, Obj>* [max_level_+1];
SkipNode<Key, Obj>* tmp = head_;
Key* cmpKey = NULL;
// Find the node we need to delete
for (h = cur_level_; h >= 1; h--) {
cmpKey = tmp->fwd_nodes[h]->getKey();
while (*cmpKey < *k) {
tmp = tmp->fwd_nodes[h];
cmpKey = tmp->fwd_nodes[h]->getKey();
}
updateVec[h] = tmp;
}
tmp = tmp->fwd_nodes[1];
cmpKey = tmp->getKey();
if (*cmpKey == *k) {
for (int i=1; i<cur_level_; i++) {
if (updateVec[i]->fwd_nodes[i] != tmp)
break;
updateVec[i]->fwd_nodes[i] = tmp->fwd_nodes[i];
}
delete tmp;
while((cur_level_ > 1) && (head_->fwd_nodes[cur_level_]->getKey() == tail_->getKey()))
cur_level_--;
return true;
}
else {
return false;
}
}
template<class Key, class Obj>
Obj* SkipList<Key, Obj>::retrieve(Key* k) {
int h = 0;
SkipNode<Key, Obj>** updateVec = new SkipNode<Key, Obj>* [max_level_+1];
SkipNode<Key, Obj>* tmp = head_;
Key* cmpKey = NULL;
// Find the node we need to delete
for (h = cur_level_; h >= 1; h--) {
cmpKey = tmp->fwd_nodes[h]->getKey();
while (*cmpKey < *k) {
tmp = tmp->fwd_nodes[h];
cmpKey = tmp->fwd_nodes[h]->getKey();
}
updateVec[h] = tmp;
}
tmp = tmp->fwd_nodes[1];
cmpKey = tmp->getKey();
if (*cmpKey == *k)
return tmp->getObj();
else
return NULL;
}
template<class Key, class Obj>
void SkipList<Key, Obj>::dump(std::ofstream &of) {
SkipNode<Key,Obj>* tmp;
tmp = head_;
while ( tmp != tail_ )
{
if ( tmp == head_ )
of << "There's the head node!" << endl << flush;
else
// Your key class must support "<<"
of << "Next node holds key: " << tmp->getKey() << endl
<< flush;
tmp = tmp->fwd_nodes[1];
}
of << "There's the tail node!" << endl << flush;
}
#endif