finidh coding skiplist, not tested yet.
This commit is contained in:
@@ -27,10 +27,12 @@ public:
|
||||
//read-only interfaces
|
||||
ListNodePosi(T) first() const { return head->succ; }
|
||||
ListNodePosi(T) last() const { return tail->prev; }
|
||||
ListNodePosi(T) prev(ListNodePosi(T) p) const { return p->prev; }
|
||||
ListNodePosi(T) next(ListNodePosi(T) p) const { return p->next; }
|
||||
ListNodePosi(T) find(T const &val) const { return find(val, size, tail); } //find val from all elements of the list
|
||||
ListNodePosi(T) find(T const &val, int n, ListNodePosi(T) p) const; //find val from a range of n elements before p
|
||||
ListNodePosi(T) search(T const &val, int n, ListNodePosi(T) p) const; //find val in a sorted List<T>
|
||||
ListNodePosi(T) search(T const &val) const { return search(val, size, tail); } //find val universally ina sorted List<T>
|
||||
ListNodePosi(T) search(T const &val) const { return search(val, size, tail); } //find val universally in a sorted List<T>
|
||||
T& operator[](int rank);
|
||||
int getSize() const { return size; }
|
||||
bool empty() const { return size == 0; }
|
||||
|
||||
14
thu_dsa/chp9/dict.h
Normal file
14
thu_dsa/chp9/dict.h
Normal file
@@ -0,0 +1,14 @@
|
||||
#ifndef DICT_H_
|
||||
#define DICT_H_
|
||||
|
||||
//Dict virtual class
|
||||
template <typename K, typename V>
|
||||
class Dict{
|
||||
public:
|
||||
virtual int size() = 0;
|
||||
virtual V get(K key) = 0;
|
||||
virtual bool put(K key, V value) = 0;
|
||||
virtual bool remove(K key) = 0;
|
||||
};
|
||||
|
||||
#endif
|
||||
88
thu_dsa/chp9/quadlist.h
Normal file
88
thu_dsa/chp9/quadlist.h
Normal file
@@ -0,0 +1,88 @@
|
||||
#ifndef QUADLIST_H_
|
||||
#define QUADLIST_H_
|
||||
|
||||
#define QuadNodePosi(T) QuadNode<T>*
|
||||
#define MAXINT (int)(0x7fffffff)
|
||||
#define MININT (int)(0x80000000)
|
||||
|
||||
template <typename T>
|
||||
class QuadNode{
|
||||
public:
|
||||
T entry;
|
||||
QuadNodePosi(T) prev;
|
||||
QuadNodePosi(T) next;
|
||||
QuadNodePosi(T) above;
|
||||
QuadNodePosi(T) below;
|
||||
|
||||
QuadNode() = default;
|
||||
QuadNode(T entry) :entry(entry) {}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class QuadList{
|
||||
private:
|
||||
QuadNodePosi(T) __head;
|
||||
QuadNodePosi(T) __tail;
|
||||
int __size;
|
||||
|
||||
public:
|
||||
//constructor
|
||||
QuadList();
|
||||
|
||||
//deconstrutor
|
||||
~QuadList();
|
||||
|
||||
//external interfaces
|
||||
|
||||
//read-only interfaces
|
||||
int size() const { return __size; }
|
||||
bool empty() const { return size() == 0; }
|
||||
QuadNodePosi(T) first() const { return empty()? nullptr : __head->next;}
|
||||
QuadNodePosi(T) last() const { return empty()? nullptr : __tail->prev;}
|
||||
QuadNodePosi(T) prev(QuadNodePosi(T) p) const { return p->prev; }
|
||||
QuadNodePosi(T) next(QuadNodePosi(T) p) const { return p->next; }
|
||||
|
||||
//writable interfaces
|
||||
void insert_before_above(QuadNodePosi(T) p, T const& entry, QuadNodePosi(T) base = nullptr);
|
||||
void insert_after_above(QuadNodePosi(T)p, T const & entry, QuadNodePosi(T) base = nullptr);
|
||||
void remove(QuadNodePosi(T) p);
|
||||
};
|
||||
|
||||
//constructor
|
||||
template <typename T>
|
||||
QuadList<T>::QuadList(){
|
||||
__head = new QuadNode<T>(MININT);
|
||||
__tail = new QuadNode<T>(MAXINT);
|
||||
__size = 0;
|
||||
__head->next = __tail;
|
||||
__tail->prev = __head;
|
||||
}
|
||||
|
||||
//writable interfaces
|
||||
|
||||
template <typename T>
|
||||
void QuadList<T>::insert_before_above(QuadNodePosi(T) p, T const & entry, QuadNodePosi(T) base){
|
||||
QuadNodePosi(T) newNode = new QuadNode<T>(entry);
|
||||
newNode->next = p;
|
||||
newNode->prev = p->prev;
|
||||
p->prev = newNode;
|
||||
newNode->prev->next = newNode;
|
||||
base->above = newNode;
|
||||
newNode->below = base;
|
||||
++__size;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void QuadList<T>::insert_after_above(QuadNodePosi(T) p, T const & entry, QuadNodePosi(T) base) {
|
||||
insert_before_above(p->prev, entry, base);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void QuadList<T>::remove(QuadNodePosi(T) p){
|
||||
//assert(p != head && p != tail);
|
||||
p->prev->next = p->next;
|
||||
p->next->prev = p->prev;
|
||||
--__size;
|
||||
}
|
||||
|
||||
#endif
|
||||
123
thu_dsa/chp9/skiplist.h
Normal file
123
thu_dsa/chp9/skiplist.h
Normal file
@@ -0,0 +1,123 @@
|
||||
#ifndef SKIPLIST_H_
|
||||
#define SKIPLIST_H_
|
||||
|
||||
#include "dict.h"
|
||||
#include "quadlist.h"
|
||||
#include "../chp3/List.h"
|
||||
#include <iostream>
|
||||
#include <cstdlib>
|
||||
#include <ctime>
|
||||
|
||||
using std::cerr;
|
||||
using std::endl;
|
||||
|
||||
template <typename K, typename V>
|
||||
class entry{
|
||||
public:
|
||||
K key;
|
||||
V value;
|
||||
|
||||
entry() = default;
|
||||
entry(K key, V value) : key(key), value(value) {}
|
||||
|
||||
operator==(entry const &e){
|
||||
return key == e.key;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename K, typename V>
|
||||
class SkipList: Dict<K, V>, List<QuadList<entry<K, V>>*>{
|
||||
protected:
|
||||
QuadNode<entry<K, V>>* skipSearch(K key);
|
||||
|
||||
public:
|
||||
//constructor
|
||||
SkipList();
|
||||
|
||||
int size() const { return first()->size(); }
|
||||
int level() const { return getSize(); }
|
||||
|
||||
V get(K key);
|
||||
bool put(K key, V value);
|
||||
bool remove(K key);
|
||||
};
|
||||
|
||||
//constructor
|
||||
template <typename K, typename V>
|
||||
SkipList<K, V>::SkipList(){
|
||||
QuadList<entry<K, V>>* qlist = new QuadList<entry<K, V>>();
|
||||
push_back(qlist);
|
||||
}
|
||||
|
||||
//internal methods
|
||||
|
||||
template <typename K, typename V>
|
||||
QuadNode<entry<K, V>>* SkipList<K, V>::skipSearch(K key) {
|
||||
while (1) {
|
||||
QuadNode<entry<K, V>>* qnode = last()->first(); //the first quadlist node of the last quadlist
|
||||
while (qnode->entry.key < key) qnode = qnode->next;
|
||||
if (qnode->entry.key == key) return qnode;
|
||||
//else
|
||||
qnode = qnode->prev;
|
||||
if (qnode->below == nullptr) return qnode;
|
||||
//else
|
||||
qnode = qnode->below;
|
||||
}
|
||||
}
|
||||
|
||||
//external interfaces
|
||||
|
||||
template <typename K, typename V>
|
||||
V SkipList<K, V>::get(K key){
|
||||
QuadNode<entry<K, V>>* res;
|
||||
res = skipSearch(key);
|
||||
if(res->entry.key != key){
|
||||
cerr << "key:" << key << "is not in SkipList!" << endl;
|
||||
}
|
||||
return res->entry.value;
|
||||
}
|
||||
|
||||
template <typename K, typename V>
|
||||
bool SkipList<K, V>::put(K key, V value){
|
||||
QuadNode<entry<K, V>>* qnode = skipSearch(key);
|
||||
QuadNode<entry<K, V>>* belowNode;
|
||||
ListNode<QuadList<entry<K, V>>*>* qlist = first();
|
||||
|
||||
while (qnode->below != nullptr) qnode = qnode->below;
|
||||
if (qnode->entry.key != key) qnode = qnode->next;
|
||||
qlist->val->insert_before_above(qnode, entry<K, V>(key, value));
|
||||
|
||||
srand((int)time(0));
|
||||
while(rand() & 1){
|
||||
belowNode = qnode->prev;
|
||||
qlist = next(qlist);
|
||||
if(qlist->val->empty()){
|
||||
push_back(new QuadList<entry<K, V>>());
|
||||
}
|
||||
while (qnode->above == nullptr) qnode = qnode->next;
|
||||
qnode = qnode->above;
|
||||
qlist->val->insert_before_above(qnode, entry<K, V>(key, value), belowNode);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename K, typename V>
|
||||
bool SkipList<K, V>::remove(K key){
|
||||
QuadNode<entry<K, V>>* qnode = skipSearch(key);
|
||||
QuadNode<entry<K, V>>* tempNode;
|
||||
ListNode<QuadList<entry<K, V>>*>* qlist = first();
|
||||
if (qnode->entry.key != key) return false;
|
||||
//else
|
||||
while (qnode->below) qnode = qnode->below;
|
||||
|
||||
while(qnode){
|
||||
tempNode = qnode;
|
||||
qlist->val->remove(qnode);
|
||||
qnode = qnode->above;
|
||||
qlist = qlist->val->next();
|
||||
delete tempNode;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user