From c77f685f1f11291b1d0d98020c5eb34e4dbf91b0 Mon Sep 17 00:00:00 2001 From: e2hang <2099307493@qq.com> Date: Wed, 30 Jul 2025 14:10:58 +0800 Subject: [PATCH] skipList --- List/skipList/main.cpp | 14 ++ List/skipList/skipList.h | 143 ++++++++++++++++++ .../skipNode跳表 => skipList/skipList跳表} | 0 List/skipList/skipNode.h | 13 ++ 4 files changed, 170 insertions(+) create mode 100644 List/skipList/main.cpp create mode 100644 List/skipList/skipList.h rename List/{skipNode/skipNode跳表 => skipList/skipList跳表} (100%) create mode 100644 List/skipList/skipNode.h diff --git a/List/skipList/main.cpp b/List/skipList/main.cpp new file mode 100644 index 0000000..5961e35 --- /dev/null +++ b/List/skipList/main.cpp @@ -0,0 +1,14 @@ +#include +#include "skipList.h" + +using namespace std; +int main() { + skipList a(100, 2, 0.5); + pair* p = new pair[50]; + p[0] = pair(1, "Test"); + p[1] = pair(2, "For"); + a.insert(p[0]); + a.insert(p[1]); + a.showLv0List(); + return 0; +} \ No newline at end of file diff --git a/List/skipList/skipList.h b/List/skipList/skipList.h new file mode 100644 index 0000000..9978ebb --- /dev/null +++ b/List/skipList/skipList.h @@ -0,0 +1,143 @@ +#pragma once +#include +#include +#include "skipNode.h" + +template +class skipList { +private: + float cutOff; //ȷ + int levels; //ǰķǿ + int dSize; //ֵԸ + int maxLevel; // + K tailKey; //ؼ + skipNode* headerNode; //ͷָ + skipNode* tailNode; //βڵָ + skipNode** last; //last[i] ʾiĽڵ + +public: + skipList(K largeKey, int maxPairs, float prob); // + std::pair* find(const K& theKey) const; //Key + int level() const; //ּ + skipNode* search(const K& theKey); //ÿһһַ + void insert(const std::pair& thePair); // + void erase(const K& theKey); // + void showWholeList() const; //ʾȫڵ + void showLv0List() const; //ʾײڵ㣨ȫݣ +}; + +template +inline skipList::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 tailPair; + tailPair.first = tailKey; + headerNode = new skipNode(tailPair, maxLevel + 1); + tailNode = new skipNode(tailPair, 0); + last = new skipNode* [maxLevel + 1]; + + //, headerNode = tailNode + for (int i = 0; i <= maxLevel; i++) { + headerNode->next[i] = tailNode; + } +} + +template +inline std::pair* skipList::find(const K& theKey) const +{ + if (theKey >= tailKey) return nullptr; + skipNode* 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 +inline int skipList::level() const +{ + int lev = 0; + while (rand() <= cutOff) lev++; + return (lev <= maxLevel) ? lev : maxLevel; +} + +template +inline skipNode* skipList::search(const K& theKey) +{ + skipNode* 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 +inline void skipList::insert(const std::pair& thePair) +{ + if (thePair.first >= tailKey) { + std::cout << "Key = " << thePair.first << " Must be < " << tailKey; + } + skipNode* 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* newNode = new skipNode(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 +inline void skipList::erase(const K& theKey) +{ + if (theKey >= tailKey) return; + + skipNode* 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 +inline void skipList::showLv0List() const +{ + skipNode* tmp = headerNode->next[0]; + while (tmp != tailNode) { + std::cout << "{" << tmp->element.first << ", " << tmp->element.second << "}" << std::endl; + tmp = tmp->next[0]; + } +} diff --git a/List/skipNode/skipNode跳表 b/List/skipList/skipList跳表 similarity index 100% rename from List/skipNode/skipNode跳表 rename to List/skipList/skipList跳表 diff --git a/List/skipList/skipNode.h b/List/skipList/skipNode.h new file mode 100644 index 0000000..a11a74a --- /dev/null +++ b/List/skipList/skipNode.h @@ -0,0 +1,13 @@ +#pragma once +#include +template +class skipNode { +public: + std::pair element; + skipNode** next; //指针数组 -> 高速公路 + //​​指针数组记录 该节点 在每一层的 下一个节点。 +public: + skipNode(const std::pair& thePair, int size) : element(thePair) { + next = new skipNode* [size]; + } +}; \ No newline at end of file