finidh coding skiplist, not tested yet.

This commit is contained in:
Shine wOng
2019-09-24 16:19:31 +08:00
parent 9966e7aa88
commit 8db337f390
4 changed files with 228 additions and 1 deletions

View File

@@ -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
View 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
View 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
View 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