LevelDB之Skiplist

#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

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值