This commit is contained in:
e2hang
2025-07-30 14:10:58 +08:00
parent eccb13de21
commit c77f685f1f
4 changed files with 170 additions and 0 deletions

14
List/skipList/main.cpp Normal file
View File

@@ -0,0 +1,14 @@
#include <iostream>
#include "skipList.h"
using namespace std;
int main() {
skipList<int, string> a(100, 2, 0.5);
pair<int, string>* p = new pair<int, string>[50];
p[0] = pair<int, string>(1, "Test");
p[1] = pair<int, string>(2, "For");
a.insert(p[0]);
a.insert(p[1]);
a.showLv0List();
return 0;
}

143
List/skipList/skipList.h Normal file
View File

@@ -0,0 +1,143 @@
#pragma once
#include <iostream>
#include <cmath>
#include "skipNode.h"
template <class K, class E>
class skipList {
private:
float cutOff; //ȷ<><C8B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
int levels; //<2F><>ǰ<EFBFBD><C7B0><EFBFBD><EFBFBD><EFBFBD>ķǿ<C4B7><C7BF><EFBFBD><EFBFBD><EFBFBD>
int dSize; //<2F>ֵ<EFBFBD><D6B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ը<EFBFBD><D4B8><EFBFBD>
int maxLevel; //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
K tailKey; //<2F><><EFBFBD><EFBFBD><EFBFBD>ؼ<EFBFBD><D8BC><EFBFBD>
skipNode<K, E>* headerNode; //ͷ<><CDB7><EFBFBD><EFBFBD>ָ<EFBFBD><D6B8>
skipNode<K, E>* tailNode; //β<>ڵ<EFBFBD>ָ<EFBFBD><D6B8>
skipNode<K, E>** last; //last[i] <20><>ʾi<CABE><69><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ľڵ<C4BD>
public:
skipList(K largeKey, int maxPairs, float prob); //<2F><><EFBFBD><EFBFBD>
std::pair<K, E>* find(const K& theKey) const; //<2F><>Key<65><79><EFBFBD><EFBFBD>
int level() const; //<2F>ּ<EFBFBD>
skipNode<K, E>* search(const K& theKey); //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ÿһ<C3BF><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD>
void insert(const std::pair<K, E>& thePair); //<2F><><EFBFBD><EFBFBD>
void erase(const K& theKey); //<2F><><EFBFBD><EFBFBD>
void showWholeList() const; //<2F><>ʾȫ<CABE><C8AB><EFBFBD>ڵ<EFBFBD>
void showLv0List() const; //<2F><>ʾ<EFBFBD><CABE><EFBFBD>ײ<EFBFBD><D7B2>ڵ㣨ȫ<E3A3A8><C8AB><EFBFBD><EFBFBD><EFBFBD>ݣ<EFBFBD>
};
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];
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, 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];
}
}

13
List/skipList/skipNode.h Normal file
View File

@@ -0,0 +1,13 @@
#pragma once
#include <utility>
template <class K, class E>
class skipNode {
public:
std::pair<K, E> element;
skipNode<K, E>** next; //指针数组 -> 高速公路
//​​指针数组记录 该节点 在每一层的 下一个节点。
public:
skipNode(const std::pair<K, E>& thePair, int size) : element(thePair) {
next = new skipNode<K, E>* [size];
}
};