skipList
This commit is contained in:
14
List/skipList/main.cpp
Normal file
14
List/skipList/main.cpp
Normal 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
143
List/skipList/skipList.h
Normal 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
13
List/skipList/skipNode.h
Normal 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];
|
||||
}
|
||||
};
|
Reference in New Issue
Block a user