#include <iostream>
#include <vector>
#include <algorithm>
#include <map>
#include <set>
#include <list>
#include <time.h>
using namespace std;
template<typename T>
//仿函数,重载()
struct Less {
bool operator () (const T & a , const T & b) const {
return a < b;
}
};
//类型comp的默认值为Less<k>
template<typename K, typename V,typename Comp = Less<K> >
class skip_list {
private:
struct skip_list_node {
int level;
const K key;
V value;
//forward指向的是指针数组
skip_list_node** forward;
skip_list_node() :key{ 0 }, value{ 0 }, level(0), forward(nullptr) {}
skip_list_node(K k, V v, int l, skip_list_node* nxt = nullptr) :key(k), value(v), level(l) {
forward = new skip_list_node * [level + 1];
for (int i = 0; i <= level; ++i) forward[i] = nxt;
}
~skip_list_node() { delete[] forward; }
};
using node = skip_list_node; //重定义,类似typedef
void init() {
/* time_t转换为uint32_t,三十二位无符号整形;
void srand(unsigned seed); 它初始化随机种子,会提供一个种子,这个种子会对应一个随机数
如果使用相同的种子后面的 rand() 函数会出现一样的随机数
time_t time(time_t *seconds)*/
srand((uint32_t)time(NULL));
level = length = 0;
head->forward = new node * [MAXL + 1];
for (int i = 0; i <= MAXL; i++)
head->forward[i] = tail;
}
int randomLevel() {
//模拟以1/p的概率往上加一层,最后和上限值取最小。
/*
Radis源码中的随机化
int zslRandomLevel(void) {
int level = 1;
while ((random() & 0xFFFF) < (ZSKIPLIST_P * 0xFFFF))
level += 1;
return (level < ZSKIPLIST_MAXLEVEL) ? level : ZSKIPLIST_MAXLEVEL;
}
*/
int lv = 1;
//random()&0xFFFF形成的数,均匀分布在区间[0,0xFFFF]上
//这个数小于(0xFFFF / 4)的概率为0.25了。
//0.75概率层1,0.75*0.25概率层2,0.75*0.25*0.25概率层3。。。
while ((rand() & S) < PS) ++lv;
return MAXL > lv ? lv : MAXL;
}
//层数
int level;
//元素个数
int length;
static const int MAXL = 32;
static const int P = 4;
static const int S = 0xFFFF;
static const int PS = S / P;
static const int INVALID = INT_MAX;
node* head, * tail;
Comp less;
//找到最大于等于key的节点,返回指向其的指针;update为传出参数,用于记录需要修改的节点
node* find(const K& key, node** update) {
node* p = head;
for (int i = level; i >= 0; i--) {
//找到该层最后一个键小于 key 的节点,然后走向下一层,记录该节点到update
while (p->forward[i] != tail && less(p->forward[i]->key, key)) {
p = p->forward[i];
}
update[i] = p;
}
//p有可能不等于
p = p->forward[0];
return p;
}
public:
struct Iter {
node* p;
Iter() : p(nullptr) {};
Iter(node* rhs) : p(rhs) {}
node* operator ->()const { return (p);}
node& operator *() const { return *p;}
bool operator == (const Iter& rhs) { return rhs.p == p;}
bool operator != (const Iter& rhs) {return !(rhs.p == p);}
void operator ++() {p = p->forward[0];}
//后置++
void operator ++(int) { p = p->forward[0]; }
};
skip_list() : head(new node()), tail(new node()), less{Comp()} {
init();
}
skip_list(Comp lambda_less) : head(new node()), tail(new node()), less{lambda_less} {
init();
}
void insert(const K& key, const V& value) {
//找到需要更新的节点并记录信息
node * update[MAXL + 1];
node* p = find(key,update);
//若key已存在,改value
if (p->key == key) {
p->value = value;
return;
}
//获取新节点最大层数
int lv = randomLevel();
if (lv > level) {
lv = ++level;
update[lv] = head;
}
//新建一个准备插入的节点
node * newNode = new node(key, value, lv);
//在0~lv层插入新节点
for (int i = lv; i >= 0; --i) {
p = update[i];
newNode->forward[i] = p->forward[i];
p->forward[i] = newNode;
}
//元素个数加一
++length;
}
bool erase(const K& key) {
node* update[MAXL + 1];
node* p = find(key, update);
//不存在该节点
if (p->key != key)return false;
for (int i = 0; i <= p->level; ++i) {
update[i]->forward[i] = p->forward[i];
}
delete p;
//可能导致最大层数减少
while (level > 0 && head->forward[level] == tail) --level;
--length;
return true;
}
Iter find(const K&key) {
node* update[MAXL + 1];
node* p = find(key, update);
if (p == tail)return tail;
if (p->key != key)return tail;
return Iter(p);
}
bool count(const K& key) {
node* update[MAXL + 1];
node* p = find(key, update);
if (p == tail)return false;
return key == p->key;
}
Iter end() {
return Iter(tail);
}
Iter begin() {
return Iter(head->forward[0]);
}
};
int main()
{
{
//使用lambda
auto cmp = [](const string& a, const string& b) {return a.length() < b.length(); };
//调用skip_list(Comp lambda_less)
//使用decltype来推导出lambda表达式的类型,然后将这个类型作为模板参数
skip_list < string, int, decltype(cmp)> list(cmp);
list.insert("aab", 1321);
list.insert("helloo", 54342);
list.insert("world", 544);
for (auto it = list.begin(); it != list.end(); it++) {
cout << it->key << " " << it->value << endl;
}
}
cout << "==================================" << endl;
{
//使用仿函数
struct cmp {
bool operator()(int a, int b) {
return a > b;
}
};
//调用skip_list()
skip_list <int, int, cmp> list{};
for (int i = 1; i <= 10; i++)list.insert(rand()%20, rand());
for (auto it = list.find(10); it != list.end(); it++) {
cout << it->key << " " << it->value << endl;
}
}
cout << "==================================" << endl;
{
//默认小于号
skip_list<int, int>list;
list.insert(1, 3);
list.insert(1, 3);
list.insert(4, 3);
list.insert(5, 3);
list.insert(2, 3);
list.insert(4, 3);
for (auto it = list.begin(); it != list.end();it++) {
cout << it->key << " " << it->value << endl;
}
}
}
测试用跳表
最新推荐文章于 2024-06-11 17:35:52 发布