SkipList跳表
参考链接:
Redis内部数据结构详解(6)——skiplist - 铁蕾的个人博客
题目:
1206. 设计跳表 - 力扣(LeetCode)
时间复杂度:
增删查均为O(logN)
模板:
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;template<class V>
struct skipListNode
{V _val;vector<skipListNode<V>*> _nextV;skipListNode(const V&v, int level):_val(v), _nextV(level,nullptr){}
};template<class V>
class skipList
{
private:typedef skipListNode<V> Node;
public:skipList():_head(new Node(V(), 1)){srand(time(0));}pair<bool, Node*> search(const V& v){Node* cur = _head;int level = _head->_nextV.size() - 1;while (level >= 0){//1、下一个节点存在且小于目标值if (cur->_nextV[level] && cur->_nextV[level]->_val < v)cur = cur->_nextV[level];//2、下一个节点不存在或者存在且大于目标值else if (cur->_nextV[level] == nullptr || cur->_nextV[level]->_val > v)--level;//3、下一个节点目标节点elsereturn make_pair<bool, Node*>(true, cur->_nextV[level]);}return make_pair<bool, Node*>(false, nullptr);}//查找位置每一层前一个节点指针vector<Node*> FindPrevNode(const V& v){Node* cur = _head;int level = _head->_nextV.size() - 1;vector<Node*> prevV(level + 1, _head);while (level >= 0){if (cur->_nextV[level] && cur->_nextV[level]->_val < v)cur = cur->_nextV[level];else if (cur->_nextV[level] == nullptr || cur->_nextV[level]->_val >= v){prevV[level] = cur;--level;}}return prevV;}void add(const V& v){vector<Node*> prevV = FindPrevNode(v);int n = RandomLevel();Node* newNode = new Node(v, n);if (n > _head->_nextV.size()) {_head->_nextV.resize(n, nullptr);prevV.resize(n, _head);}for (size_t i = 0; i < n; ++i){newNode->_nextV[i] = prevV[i]->_nextV[i];prevV[i]->_nextV[i] = newNode;}}bool erase(const V& v){vector<Node*> prevV = FindPrevNode(v);//没有就删除失败if (prevV[0]->_nextV[0] == nullptr || prevV[0]->_nextV[0]->_val != v)return false;else{Node* del = prevV[0]->_nextV[0];for (int i = 0; i < del->_nextV.size(); i++){prevV[i]->_nextV[i] = del->_nextV[i];}delete del;//如果删除节点是层数最高的,把头节点降下一层int i = _head->_nextV.size() - 1;while (i >= 0){if (_head->_nextV[i] == nullptr)--i;elsebreak;}_head->_nextV.resize(i + 1);return true;}}int RandomLevel(){size_t level = 1;// rand() ->[0, RAND_MAX]之间while (rand() <= RAND_MAX * _p && level < _maxLevel){++level;}return level;}void Print(){Node* cur = _head;while (cur){printf("%d\n", cur->_val);// 打印每个每个cur节点for (auto e : cur->_nextV){printf("%2s", "↓");}printf("\n");cur = cur->_nextV[0];}}private:Node* _head; //头节点double _p = 0.25; //当前层数新增一层的概率因子size_t _maxLevel = 32; //最大层数
};int main()
{skipList<int> skiplist;skiplist.add(2);skiplist.add(1);skiplist.add(3);skiplist.add(7);skiplist.add(4);skiplist.add(8);skiplist.add(2);skiplist.Print();return 0;
}