//跳过列表中使用的节点类型
//具有下一个和元素字段的节点;元素是一对<const K,E>
//接下来是指针的一维数组
#ifndef SKIPNODE_H
#define SKIPNODE_H
template<typename K, typename E>
struct skipNode
{
typedef pair<const K, E> pairType;
pairType element;
skipNode<K, E> **next; // 指针数组
skipNode(const pairType& thePair, int size) : element(thePair){next = new skipNode<K, E>* [size];}
};
#endif // !SKIPNODE_H
// 跳表数据结构,实现字典
#ifndef SKIPLIST_H
#define SKIPLIST_H
#include <iostream>
#include <math.h>
#include "dictionary.h"
#include "skipNode.h"
#include "myExceptions.h"
template<typename K, typename E>
class skipList : public dictionary<K, E>
{
public:
skipList(K, int maxPairs = 10000, float prob = 0.5);
~skipList();
bool empty() const {return dSize == 0;}
int size() const {return dSize;}
pair<const K, E>* find(const K&) const;
void erase(const K&);
void insert(const pair<const K, E>&);
void output(ostream& out) const;
protected:
float cutOff; // 用来的确定层数
int level() const; // 生成一个随机级别数
int levels; // 当前最大的非空链表
int dSize; // 字典的数对个数
int maxLevel; // 允许的最大链表层数
K tailKey; // 最大挂按键自
skipNode<K, E>* search(const K&) const; // 搜索保存最后的节点
skipNode<K, E>* headerNode; // 头节点指针
skipNode<K, E>* tailNode; // 尾结点指针
skipNode<K, E>** last; // last[i] 表示 i 层的最后节点
};
template<typename K, typename E>
// 关键字 数对 概率
skipList<K, E>::skipList(K largeKey, int maxPairs, float prob)
{// 构造函数,关键字小于 largeKey 且数对个数 size 最多为 maxPairs。0 < prob < 1
cutOff = prob * RAND_MAX; // 32767
maxLevel = (int) ceil(logf((float)maxPairs) / logf(1 / prob)); // ceil 取整 logf 返回以 e 为底单精度数的对数值
levels = 0; // 初始化级数
dSize = 0;
tailKey = largeKey; // 最大关键字
// 生成头结点、尾结点和数组 last
pair<K, E> tailPair;
tailPair.first = tailKey; // 最大关键字
headerNode = new skipNode<K, E> (tailPair, maxLevel + 1); // 头节点指针
tailNode = new skipList<K, E> (tailPair, 0);
last = new skipNode<K, E>* [maxLevel + 1]; // 允许最大的链表层数
// 链表为空时,任意级链表中的头节点都指向尾节点
for (int i = 0; i <= maxLevel; i++)
headerNode->next[i] = tailNode;
}
template<class K, class E>
skipList<K,E>::~skipList()
{// 析构函数 最后删除所有节点和数组
skipNode<K,E> *nextNode;
// 按照 0 级链删除所有节点
while (headerNode != tailNode)
{
nextNode = headerNode->next[0];
delete headerNode;
headerNode = nextNode;
}
delete tailNode;
delete [] last;
}
template<typename K, typename E>
pair<const K, E>* skipList<K, E>::find(const K& theKey) const
{// 返回匹配的数对的指针
// 如果没有匹配的数对,返回NULL
if (theKey >= tailKey)
return NULL; // 没有可能的匹配的数对
// 位置 beforeNode 是关键字为 theKey 的节点之前最右边的位置
skipNode<K, E>* beforeNode = headerNode;
for (int i = levels; i >= 0; i--) // 从上级链表到下级链表
// 跟踪 i 级链表指针
while (beforeNode->next[i]->element.first < theKey)
beforeNode = beforeNode->next[i];
return NULL; // 无匹配的数对
}
template<typename K, typename E>
int skipList<K, E>::level() const
{// 返回一个表示链表级的随机数,这个数不大于 maxLevel
int lev = 0;
while (rand() <= cutOff)
lev++;
return (lev <= maxLevel) ? lev : maxLevel;
}
template<typename K, typename E>
skipNode<K, E>* skipList<K, E>::search(const K& theKey) const
{// 搜索关键字 theKey,把每一级链表中要查看的最后一个节点存储在数组 last中
// 返回包含关键字 theKey 的节点
// 位置 beforeNode 是关键字为 theKey 的节点之前最右边的位置
skipNode<K, E>* beforeNode = headerNode;
for (int i = levels; i >= 0; i--)
{
while (beforeNode->next[i]->element.first < theKey)
beforeNode = beforeNode->next[i];
last[i] = beforeNode; // 最后一级链表 i 的节点
}
return beforeNode->next[0];
}
template<typename K, typename E>
void skipList<K, E>::insert(const pair<const K, E>& thePair)
{// 把数对 thePair 插入字典,覆盖其关键字相同的已存在的数对
if (thePair.first >= tailKey) // 关键字太大
{
ostringstream s;
s << "Key = " << thePair.first << " 必须小于 " << tailKey;
throw illegalParameterValue(s.str());
}
// 查看关键字为 theKey 的数对是否已经存在
skipNode<K, E>* theNode = search(thePair.first);
if (theNode->element.first == thePair.first)
{// 若存在,则更新该数对的值
theNode->element.second = thePair.second;
return;
}
// 若不在,则确定新节点所在的级链表
int theLevel = level(); // 新节点的级
// 使级 theLevel 为 <= levels + 1
if (theLevel > levels)
{
theLevel = ++levels;
last[theLevel] = headerNode;
}
// 在节点 theNode 之后插入新节点
skipNode<K, E>* newNode = new skipNode<K, E>(thePair, theLevel + 1);
for (int i = 0; i <= theLevel; i++)
{// 插入 i 级链表
newNode->next[i] = last[i]->next[i];
last[i]->next[i] = newNode;
}
dSize++;
return;
}
template<typename K, typename E>
void skipList<K, E>::erase(const K& theKey)
{// 删除关键字等于 theKey 的数对
if (theKey >= tailKey) // 关键字太大
return;
// 查看是否有匹配的数对
skipNode<K, E>* theNode = search(theKey);
if (theNode->element.first != theKey) // 不存在
return;
// 从跳表中删除节点
for (int i = 0; i <= levels && last[i]->next[i] == theNode; i++)
last[i]->next[i] = theNode->next[i];
// 更新链表级
while (levels > 0 && headerNode->next[levels] == tailNode)
levels--;
delete theNode;
dSize--;
}
#endif // !SKIPLIST_H