diff --git a/thu_dsa/chp3/List.h b/thu_dsa/chp3/List.h index 6094a6e..c91452c 100644 --- a/thu_dsa/chp3/List.h +++ b/thu_dsa/chp3/List.h @@ -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 - ListNodePosi(T) search(T const &val) const { return search(val, size, tail); } //find val universally ina sorted List + ListNodePosi(T) search(T const &val) const { return search(val, size, tail); } //find val universally in a sorted List T& operator[](int rank); int getSize() const { return size; } bool empty() const { return size == 0; } diff --git a/thu_dsa/chp9/dict.h b/thu_dsa/chp9/dict.h new file mode 100644 index 0000000..b5d121d --- /dev/null +++ b/thu_dsa/chp9/dict.h @@ -0,0 +1,14 @@ +#ifndef DICT_H_ +#define DICT_H_ + +//Dict virtual class +template +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 diff --git a/thu_dsa/chp9/quadlist.h b/thu_dsa/chp9/quadlist.h new file mode 100644 index 0000000..e973eda --- /dev/null +++ b/thu_dsa/chp9/quadlist.h @@ -0,0 +1,88 @@ +#ifndef QUADLIST_H_ +#define QUADLIST_H_ + +#define QuadNodePosi(T) QuadNode* +#define MAXINT (int)(0x7fffffff) +#define MININT (int)(0x80000000) + +template +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 +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 +QuadList::QuadList(){ + __head = new QuadNode(MININT); + __tail = new QuadNode(MAXINT); + __size = 0; + __head->next = __tail; + __tail->prev = __head; +} + +//writable interfaces + +template +void QuadList::insert_before_above(QuadNodePosi(T) p, T const & entry, QuadNodePosi(T) base){ + QuadNodePosi(T) newNode = new QuadNode(entry); + newNode->next = p; + newNode->prev = p->prev; + p->prev = newNode; + newNode->prev->next = newNode; + base->above = newNode; + newNode->below = base; + ++__size; +} + +template +void QuadList::insert_after_above(QuadNodePosi(T) p, T const & entry, QuadNodePosi(T) base) { + insert_before_above(p->prev, entry, base); +} + +template +void QuadList::remove(QuadNodePosi(T) p){ + //assert(p != head && p != tail); + p->prev->next = p->next; + p->next->prev = p->prev; + --__size; +} + +#endif diff --git a/thu_dsa/chp9/skiplist.h b/thu_dsa/chp9/skiplist.h new file mode 100644 index 0000000..547dac9 --- /dev/null +++ b/thu_dsa/chp9/skiplist.h @@ -0,0 +1,123 @@ +#ifndef SKIPLIST_H_ +#define SKIPLIST_H_ + +#include "dict.h" +#include "quadlist.h" +#include "../chp3/List.h" +#include +#include +#include + +using std::cerr; +using std::endl; + +template +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 +class SkipList: Dict, List>*>{ +protected: + QuadNode>* 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 +SkipList::SkipList(){ + QuadList>* qlist = new QuadList>(); + push_back(qlist); +} + +//internal methods + +template +QuadNode>* SkipList::skipSearch(K key) { + while (1) { + QuadNode>* 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 +V SkipList::get(K key){ + QuadNode>* res; + res = skipSearch(key); + if(res->entry.key != key){ + cerr << "key:" << key << "is not in SkipList!" << endl; + } + return res->entry.value; +} + +template +bool SkipList::put(K key, V value){ + QuadNode>* qnode = skipSearch(key); + QuadNode>* belowNode; + ListNode>*>* qlist = first(); + + while (qnode->below != nullptr) qnode = qnode->below; + if (qnode->entry.key != key) qnode = qnode->next; + qlist->val->insert_before_above(qnode, entry(key, value)); + + srand((int)time(0)); + while(rand() & 1){ + belowNode = qnode->prev; + qlist = next(qlist); + if(qlist->val->empty()){ + push_back(new QuadList>()); + } + while (qnode->above == nullptr) qnode = qnode->next; + qnode = qnode->above; + qlist->val->insert_before_above(qnode, entry(key, value), belowNode); + } + return true; +} + +template +bool SkipList::remove(K key){ + QuadNode>* qnode = skipSearch(key); + QuadNode>* tempNode; + ListNode>*>* 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