Files
Data-Structure/List/skipList/skipList.h
2025-07-30 14:10:58 +08:00

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];
}
}