跳錶SkipList詳解
阿新 • • 發佈:2018-12-21
有序表的搜尋:
如果要搜尋23, 43, 59要比較的次數分別為2, 4, 6次,我們把一些節點提取出來作為索引,生成如下
那麼搜尋43可以跳過23, 搜尋 59可以跳過23, 43;實現了搜尋的加速,提高層數
尋找59,我們可以跳過更多的節點
調錶的實現:
- 搜尋時,從上往下找,上層的數作為filter,類似於二分查詢
- 每一個數的層數由插入時,通過一定的概率決定在多少層
#include <iostream> #include <vector> #include <cstdlib> using namespace std; class SkipListNode { public: int value; vector<SkipListNode*> nextNodes; SkipListNode(int v) { value = v; } }; class SkipList { private: SkipListNode* head; int maxLevel; int size; const double PROBABILITY = 0.5; public: SkipList() { head = new SkipListNode(-1); head->nextNodes.push_back(NULL); maxLevel = 0; size = 0; } SkipListNode* getHead() { return head; } bool contains(int e) { SkipListNode* node = find(e); return node != NULL && node->value != -1 && node->value == e; } void add(int newValue) { if (!contains(newValue)) { size++; int level = 0; while (rand() % 1001 / 1000.0 > PROBABILITY) { level++; } while (level > maxLevel) { head->nextNodes.push_back(NULL); maxLevel++; } SkipListNode* newNode = new SkipListNode(newValue); SkipListNode* current = head; do { current = findNext(newValue, current, level); newNode->nextNodes.insert(newNode->nextNodes.begin(), current->nextNodes[level]);//從第一個位置開始加入,推上去 current->nextNodes[level] = newNode; } while (level-- > 0); } } void move(int deleteValue) { if (contains(deleteValue)) { SkipListNode* deleteNode = find(deleteValue); size--; int level = maxLevel; SkipListNode* current = head; do { current = findNextLess(deleteValue, current, level); if (deleteNode->nextNodes.size() > level) { current->nextNodes[level] = deleteNode->nextNodes[level]; } } while (level-- > 0); delete deleteNode; } } private: //Return the node at a given level with highest value <= e //刪除節點多少時候需要用 SkipListNode* findNext(int e, SkipListNode* current, int level) { SkipListNode* next = current->nextNodes[level]; while (next != NULL) { int value = next->value; if (e < value) { break; } current = next; next = current->nextNodes[level]; } return current; } //Return the node at a given level with highest value < e SkipListNode* findNextLess(int e, SkipListNode* current, int level) { SkipListNode* next = current->nextNodes[level]; while (next != NULL) { int value = next->value; if (e <= value) { break; } current = next; next = current->nextNodes[level]; } return current; } SkipListNode* find(int e, SkipListNode* current, int level) { do { current = findNext(e, current, level); } while (level-- > 0);//保證第0層要搜尋到 return current; } SkipListNode* find(int e) { return find(e, head, maxLevel); } }; int main() { SkipList test; test.add(1); test.add(3); test.add(4); test.move(3); cout << test.contains(3) << endl; cout << test.contains(9) << endl; system("pause"); return 0; }