标签:lis skiplist plist 实施 oid cti name -- 修改
Dictionary.hpp
#ifndef Dictionary_hpp #define Dictionary_hpp #define N_CHAR (0x80 - 0x20) //只考虑可打印字符 //词典Dictionary模版类 template <typename K,typename V> struct Dictionary { public: virtual int size() const = 0; //当前词条总数 virtual bool put(K,V) = 0; //插入词条(禁止雷同词条时可能失败) virtual V* get(K k) = 0; //读取词条 virtual bool remove(K k) = 0; //删除词条 }; #endif /* Dictionary_hpp */
QuadlistNode.hpp
#ifndef QuadlistNode_hpp #define QuadlistNode_hpp #include <iostream> #define QlistNodePosi(T) QuadlistNode<T>* //跳转表节点位置 template <typename T> struct QuadlistNode { T entry; //所存词条 QlistNodePosi(T) pred; //前驱 QlistNodePosi(T) succ; //后继 QlistNodePosi(T) above; //上邻 QlistNodePosi(T) below; //下邻 QuadlistNode(T e = T(),QlistNodePosi(T) p = NULL,QlistNodePosi(T) s = NULL,QlistNodePosi(T) a = NULL,QlistNodePosi(T) b = NULL) : entry(e),pred(p),succ(s),above(a),below(b) {} QlistNodePosi(T) insertAsSuccAbove(T const& e,QlistNodePosi(T) b = NULL); //插入新节点,以当前节点为前驱,以节点b为下邻 }; template <typename T> QlistNodePosi(T) QuadlistNode<T>::insertAsSuccAbove(const T &e,QlistNodePosi(T) b ) { QlistNodePosi(T) x = new QuadlistNode<T>(e, this, succ, NULL, b); succ->pred = x; succ = x; //设置水平逆向链接 if (b) { b -> above = x; //设置垂直逆向链接 } return x; //返回新节点的位置 } #endif /* QuadlistNode_hpp */
Quadlist.hpp
#ifndef Quadlist_hpp #define Quadlist_hpp #include "QuadlistNode.hpp" #include "ListNode.hpp" template <typename T> class Quadlist { private: //规模,头哨兵,尾哨兵 int _size; QlistNodePosi(T) header; QlistNodePosi(T) trailer; protected: void init(); int clear(); public: Quadlist() { init(); } ~Quadlist() { clear(); delete header; delete trailer; } //只读访问接口 Rank size() const { return _size; } bool empty() const { return _size <= 0; } QlistNodePosi(T) first() { return header -> succ; } QlistNodePosi(T) last() { return trailer -> pred; } bool valid(QlistNodePosi(T) p) { return p && (trailer != p) && (header != p); } //可写访问接口 T remove(QlistNodePosi(T) p); //删除(合法)位置p处的节点,返回被删除节点的数值 QlistNodePosi(T) insertAfterAbove(T const& e,QlistNodePosi(T) p,QlistNodePosi(T) b = NULL); //遍历 void traverse(void (*)(T&)); //遍历各节点,一次实施指定操作(函数指针,只读或局部修改) template <typename VST> void traverse(VST&); //操作器 }; template <typename T> void Quadlist<T>::init() { header = new QuadlistNode<T>; trailer = new QuadlistNode<T>; header->succ = trailer; header->pred = NULL; trailer->pred = header; trailer->succ = NULL; header->above = trailer->above = NULL; header->below = trailer->below = NULL; _size = 0; } template <typename T> QlistNodePosi(T) Quadlist<T>::insertAfterAbove(const T &e, QlistNodePosi(T) p,QlistNodePosi(T) b) { _size++; return p -> insertAsSuccAbove(e, b); } template <typename T> T Quadlist<T>::remove(QlistNodePosi(T) p) { //assert: p为Quadlist中的合法位置 p -> pred -> succ = p -> succ; p -> succ -> pred = p -> pred; _size--; T e = p -> entry; delete p; //备份词条,释放节点 return e; //返回词条 } template <typename T> int Quadlist<T>::clear() { //清空Quadlist int oldSize = _size; while (0 < _size) { remove(header -> succ); //逐个删除所有节点 } return oldSize; } #endif /* Quadlist_hpp */
Skiplist.hpp
#ifndef Skiplist_hpp #define Skiplist_hpp #include "Quadlist.hpp" #include "Dictionary.hpp" #include "Entry.hpp" #include "List.hpp" //跳转表 template <typename K,typename V> class Skiplist : public Dictionary<K, V>, public List<Quadlist<Entry<K,V>> *> { protected: bool skipSearch(ListNode<Quadlist<Entry<K,V>>* > *qlist, QuadlistNode<Entry<K,V>> * &p,K& k); public: int size() const { return this->empty() ? 0 : this->last()->data->size(); //底层Quadlist的规模 } int level() { return List<Quadlist<Entry<K,V>> *>::size(); //层高==#Quadlist,不一定要开放 } bool put(K,V); //插入(注意与map有区别----Skiplist允许词条重复,故必然成功) V* get(K k); //读取 bool remove(K k); //删除 Skiplist() {} }; template <typename K,typename V> V* Skiplist<K,V>::get(K k) { if (this->empty()) { return NULL; } ListNode<Quadlist<Entry<K, V>> *> *qlist = this->first(); QuadlistNode<Entry<K, V>> *p = qlist->data->first(); //首节点开始 return skipSearch(qlist, p, k) ? &(p -> entry.value) : NULL; } template <typename K,typename V> bool Skiplist<K,V>::skipSearch(ListNode<Quadlist<Entry<K, V> > *> *qlist, QuadlistNode<Entry<K, V> > *&p, K &k) { //从指定层qlist的首节点p出发,向右,向下查找目标关键码k while (true) { //在每一层 while (p->succ && (p->entry.key <= k)) { //从前向后查找 p = p->succ; //知道出现更大的key或溢出至trailer } p = p -> pred; //此时倒回一步,即可判断是否命中,否则转入下一层 if (p -> pred && (k == p->entry.key)) { return true; } qlist = qlist -> succ; if (!qlist -> succ) { return false; //若已到穿透底层,则意味着失败 } p = (p -> pred) ? p -> below : qlist -> data -> first(); //否则转至当前塔的下一节点 } } template <typename K,typename V> bool Skiplist<K,V>::put(K k, V v) { Entry<K, V> e = Entry<K, V>(k, v); //待插入的词条(将被随机的插入多个副本) if (this->empty()) { this->insertAsFirst(new Quadlist<Entry<K, V>>); //插入首个Entry } ListNode<Quadlist<Entry<K, V>> *> *qlist = this->first(); //从顶层四联表的首节点出发 QuadlistNode<Entry<K, V>> *p = qlist->data->first(); if (skipSearch(qlist, p, k)) { while (p->below) { //查找适当的插入位置(不大于关键码k的最后一个节点p) p = p -> below; //若已有雷同词条,则需强制转至塔底 } } qlist = this->last(); //以下,紧邻与p的右侧,一座新塔将自底而上逐层生长 QuadlistNode<Entry<K, V>> *b = qlist->data->insertAfterAbove(e, p); while (rand() & 1) { //经投掷硬币,若确定新塔需要在长高一层,则找出不低于此高度的最近前驱 while (qlist->data->valid(p) && !p->above) { p = p -> pred; } if (!qlist->data->valid(p)) { //若该前驱是header if (qlist == this->first()) { //且当前已是最顶层,则意味着必须首先创建新的一层,然后将p转至上一层Skiplist的header this->insertAsFirst(new Quadlist<Entry<K, V>>); } p = qlist->pred->data->first()->pred; }else{ //否则可径自 将p提高至该高度 p = p -> above; } qlist = qlist -> pred; //上升一层,并在该层 b = qlist ->data->insertAfterAbove(e, p, b); //将新节点插入p之后、b之上 } return true; } //跳转表词条删除算法 template <typename K,typename V> bool Skiplist<K,V>::remove(K k) { if (this->empty()) { return false; //空表情况 } ListNode<Quadlist<Entry<K, V>> *> *qlist = this->first(); QuadlistNode<Entry<K, V>> *p = qlist->data->first(); if (!skipSearch(qlist, p, k)) { return false; //目标词条不存在,直接返回 } do{ //若目标词条不存在,则逐层拆除与之对应的塔 QuadlistNode<Entry<K, V>> *lower = p->below; qlist->data->remove(p); p = lower; //删除当前层节点,再 qlist = qlist -> succ; //转入下一层 }while(qlist->succ); while (!this->empty() && this->first()->data->empty()) { //逐一的清除已可能不含词条的顶层Quadlist List<Quadlist<Entry<K,V>> *>::remove(this->first()); } return true; //删除操作成功完成 } #endif /* Skiplist_hpp */
标签:lis skiplist plist 实施 oid cti name -- 修改
原文地址:https://www.cnblogs.com/gkp307/p/9621114.html