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