标签: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