debug skiplist, all tests passed. But I sincerely doubt my coding ability.

This commit is contained in:
Shine wOng
2019-09-24 20:44:11 +08:00
parent 3937604aa7
commit f1accda023
5 changed files with 134 additions and 22 deletions

View File

@@ -27,8 +27,8 @@ 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) prev(ListNodePosi(T) p) const { return p->prev == head? nullptr: p->prev; }
ListNodePosi(T) next(ListNodePosi(T) p) const { return p->succ == tail? nullptr: p->succ; }
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>

View File

@@ -5,7 +5,7 @@
template <typename K, typename V>
class Dict{
public:
virtual int size() = 0;
virtual int size() const = 0;
virtual V get(K key) = 0;
virtual bool put(K key, V value) = 0;
virtual bool remove(K key) = 0;

View File

@@ -29,20 +29,20 @@ 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) first() const { return __head->next;}
QuadNodePosi(T) last() const { return __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 sethead(T entry) { __head->entry = entry; }
void settail(T entry) { __tail->entry = entry; }
void connectTo(QuadList<T>* down);
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);
@@ -51,15 +51,26 @@ public:
//constructor
template <typename T>
QuadList<T>::QuadList(){
__head = new QuadNode<T>(MININT);
__tail = new QuadNode<T>(MAXINT);
__head = new QuadNode<T>();
__tail = new QuadNode<T>();
__size = 0;
__head->next = __tail;
__head->prev = __tail;
__tail->next = __head;
__tail->prev = __head;
}
//writable interfaces
template <typename T>
void QuadList<T>::connectTo(QuadList<T>* down){
//assert(down != nullptr);
__head->below = down->__head;
__tail->below = down->__tail;
down->__head->above = __head;
down->__tail->above = __tail;
}
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);
@@ -67,7 +78,7 @@ void QuadList<T>::insert_before_above(QuadNodePosi(T) p, T const & entry, QuadNo
newNode->prev = p->prev;
p->prev = newNode;
newNode->prev->next = newNode;
base->above = newNode;
if(base) base->above = newNode;
newNode->below = base;
++__size;
}

View File

@@ -5,6 +5,7 @@
#include "quadlist.h"
#include "../chp3/List.h"
#include <iostream>
#include <iomanip>
#include <cstdlib>
#include <ctime>
@@ -20,7 +21,7 @@ public:
entry() = default;
entry(K key, V value) : key(key), value(value) {}
operator==(entry const &e){
bool operator==(entry const &e){
return key == e.key;
}
};
@@ -34,18 +35,21 @@ public:
//constructor
SkipList();
int size() const { return first()->size(); }
int size() const { return first()->val->size(); }
int level() const { return getSize(); }
V get(K key);
bool put(K key, V value);
bool remove(K key);
void print() const;
};
//constructor
template <typename K, typename V>
SkipList<K, V>::SkipList(){
QuadList<entry<K, V>>* qlist = new QuadList<entry<K, V>>();
qlist->sethead(entry<K, V>(MININT, 0));
qlist->settail(entry<K, V>(MAXINT, 0));
push_back(qlist);
}
@@ -53,8 +57,8 @@ SkipList<K, V>::SkipList(){
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
QuadNode<entry<K, V>>* qnode = last()->val->first(); //the first quadlist node of the last quadlist
while (1) {
while (qnode->entry.key < key) qnode = qnode->next;
if (qnode->entry.key == key) return qnode;
//else
@@ -81,22 +85,33 @@ 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();
ListNode<QuadList<entry<K, V>>*> *qlist = first();
QuadList<entry<K, V>> *newlist;
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));
if (next(qlist) == nullptr) {
newlist = new QuadList<entry<K, V>>();
newlist->sethead(entry<K, V>(MININT, 0));
newlist->settail(entry<K, V>(MAXINT, 0));
newlist->connectTo(qlist->val);
push_back(newlist);
}
srand((int)time(0));
while(rand() & 1){
while(rand() % 2 == 0){
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);
if (next(qlist) == nullptr) {
newlist = new QuadList<entry<K, V>>();
newlist->sethead(entry<K, V>(MININT, 0));
newlist->settail(entry<K, V>(MAXINT, 0));
newlist->connectTo(qlist->val);
push_back(newlist);
}
}
return true;
}
@@ -114,10 +129,44 @@ bool SkipList<K, V>::remove(K key){
tempNode = qnode;
qlist->val->remove(qnode);
qnode = qnode->above;
qlist = qlist->val->next();
qlist = next(qlist);
delete tempNode;
}
//remove level if empty
qlist = prev(last());
while(qlist && qlist->val->empty()){
pop_back();
qlist = prev(qlist);
}
return true;
}
template <typename K, typename V>
void SkipList<K, V>::print() const{
QuadList<entry<K, V>>* qlist = first()->val;
QuadNode<entry<K, V>>* qnode;
QuadNode<entry<K, V>>* tempNode;
int* currLevel = new int[size()], idx = 0;
for(qnode = qlist->first(); qnode->entry.key != MAXINT; qnode = qnode->next){
currLevel[idx] = 0;
tempNode = qnode;
while(tempNode){
currLevel[idx]++;
tempNode = tempNode->above;
}
++idx;
}
for (int jx = level(); jx != 0; --jx) {
idx = 0;
for (qnode = qlist->first(); qnode->entry.key != MAXINT; qnode = qnode->next){
if (currLevel[idx++] >= jx) cout << qnode->entry.key << '\t';
else cout << " " << '\t';
}
cout << endl;
}
}
#endif

View File

@@ -0,0 +1,52 @@
#include "skiplist.h"
#include <iostream>
#include <cassert>
using std::cout;
using std::endl;
void basic_test();
void insert_delete_test();
int main(){
cout << "begin tests ..." << endl;
basic_test();
insert_delete_test();
cout << "All tests passed." << endl;
system("pause");
return 0;
}
void basic_test(){
SkipList<int, int> slist;
assert(slist.size() == 0);
assert(slist.level() == 1);
slist.print();
assert(slist.remove(0) == false);
cout << "basic_test passed." << endl;
}
void insert_delete_test(){
SkipList<int, int> slist;
int src[15] = { 5, 9, 0, 2, 3, 6, 1, 7, 4, 8, 3, 8, 4, 7, 7 };
srand((unsigned int)time(0));
for (int ix = 0; ix != 15; ++ix) {
slist.put(src[ix], src[ix]);
cout << "This is the " << ix + 1 << "th insert, the level is " << slist.level() << endl;
slist.print();
}
cout << endl;
for(int ix = 0; ix != 15; ++ix){
slist.remove(src[ix]);
cout << "This is the " << ix + 1 << "th delete, the level is " << slist.level() << endl;
slist.print();
}
cout << "insert_delete test passed." << endl;
}