144 lines
3.6 KiB
C++
144 lines
3.6 KiB
C++
#pragma once
|
|
#include <iostream>
|
|
#include <cmath>
|
|
#include "skipNode.h"
|
|
|
|
template <class K, class E>
|
|
class skipList {
|
|
private:
|
|
float cutOff; //确定层数
|
|
int levels; //当前最大的非空链表
|
|
int dSize; //字典的数对个数
|
|
int maxLevel; //允许的最大链表层数
|
|
K tailKey; //最大关键字
|
|
skipNode<K, E>* headerNode; //头结点指针
|
|
skipNode<K, E>* tailNode; //尾节点指针
|
|
skipNode<K, E>** last; //last[i] 表示i层最后的节点
|
|
|
|
public:
|
|
skipList(K largeKey, int maxPairs, float prob); //构造
|
|
std::pair<K, E>* find(const K& theKey) const; //用Key查找
|
|
int level() const; //分级
|
|
skipNode<K, E>* search(const K& theKey); //搜索并把每一级链表最后一个地址保存
|
|
void insert(const std::pair<K, E>& thePair); //插入
|
|
void erase(const K& theKey); //消除
|
|
void showWholeList() const; //显示全部节点
|
|
void showLv0List() const; //显示最底层节点(全部数据)
|
|
};
|
|
|
|
template<class K, class E>
|
|
inline skipList<K, E>::skipList(K largeKey, int maxPairs, float prob)
|
|
{
|
|
cutOff = prob * RAND_MAX;
|
|
maxLevel = (int)ceil(logf((float)maxPairs)) / logf(1 / prob) - 1;
|
|
levels = 0;
|
|
dSize = 0;
|
|
tailKey = largeKey;
|
|
|
|
std::pair<K, E> tailPair;
|
|
tailPair.first = tailKey;
|
|
headerNode = new skipNode<K, E>(tailPair, maxLevel + 1);
|
|
tailNode = new skipNode<K, E>(tailPair, 0);
|
|
last = new skipNode<K, E>* [maxLevel + 1];
|
|
|
|
//链表空, headerNode = tailNode
|
|
for (int i = 0; i <= maxLevel; i++) {
|
|
headerNode->next[i] = tailNode;
|
|
}
|
|
}
|
|
|
|
template<class K, class E>
|
|
inline std::pair<K, E>* skipList<K, E>::find(const K& theKey) const
|
|
{
|
|
if (theKey >= tailKey) return nullptr;
|
|
skipNode<K, E>* beforeNode = headerNode;
|
|
for (int i = levels; i >= 0; i--) {
|
|
while (beforeNode->next[i]->element.first < theKey) {
|
|
beforeNode = beforeNode->next[i];
|
|
}
|
|
}
|
|
if (beforeNode->next[0]->element.first == theKey) {
|
|
return &beforeNode->next[0]->element;
|
|
}
|
|
return nullptr;
|
|
}
|
|
|
|
template<class K, class E>
|
|
inline int skipList<K, E>::level() const
|
|
{
|
|
int lev = 0;
|
|
while (rand() <= cutOff) lev++;
|
|
return (lev <= maxLevel) ? lev : maxLevel;
|
|
}
|
|
|
|
template<class K, class E>
|
|
inline skipNode<K, E>* skipList<K, E>::search(const K& 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;
|
|
}
|
|
return beforeNode->next[0];
|
|
}
|
|
|
|
template<class K, class E>
|
|
inline void skipList<K, E>::insert(const std::pair<K, E>& thePair)
|
|
{
|
|
if (thePair.first >= tailKey) {
|
|
std::cout << "Key = " << thePair.first << " Must be < " << tailKey;
|
|
}
|
|
skipNode<K, E>* theNode = search(thePair.first);
|
|
if (theNode->element.first == thePair.first) {
|
|
theNode->element.second = thePair.second;
|
|
return;
|
|
}
|
|
|
|
int theLevel = level();
|
|
|
|
if (theLevel > levels) {
|
|
theLevel = ++levels;
|
|
last[theLevel] = headerNode;
|
|
}
|
|
|
|
skipNode<K, E>* newNode = new skipNode<K, E>(thePair, theLevel + 1);
|
|
for (int i = 0; i <= theLevel; i++) {
|
|
newNode->next[i] = last[i]->next[i];
|
|
last[i]->next[i] = newNode;
|
|
}
|
|
|
|
dSize++;
|
|
return;
|
|
}
|
|
|
|
template<class K, class E>
|
|
inline void skipList<K, E>::erase(const K& 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--;
|
|
}
|
|
|
|
template<class K, class E>
|
|
inline void skipList<K, E>::showLv0List() const
|
|
{
|
|
skipNode<K, E>* tmp = headerNode->next[0];
|
|
while (tmp != tailNode) {
|
|
std::cout << "{" << tmp->element.first << ", " << tmp->element.second << "}" << std::endl;
|
|
tmp = tmp->next[0];
|
|
}
|
|
}
|