I ran into the fact that my program works incorrectly if I "just" launch it for execution. But if you put breakpoints in IDE, it works fine. I implement the list with gaps and for the test I just fill it with numbers from 1 to 10. If I run "just", it turns out that
lvl 0 :1 -> 2 -> 3 -> 4 -> 5 -> 6 -> 7 -> 8 -> 9 -> 10 lvl 1 :1 -> 2 -> 3 -> 4 -> 5 -> 6 -> 7 -> 8 -> 9 -> 10 lvl 2 :1 -> 2 -> 3 -> 4 -> 5 -> 6 -> 7 -> 8 -> 9 -> 10 lvl 3 :1 -> 2 -> 3 -> 4 -> 5 -> 6 -> 7 -> 8 -> 9 -> 10 Or that:
lvl 0 :1 -> 2 -> 3 -> 4 -> 5 -> 6 -> 7 -> 8 -> 9 -> 10 lvl 1 :1 lvl 2 :1 lvl 3 :1 If with breakpoints, then about this:
lvl 0 :1 -> 2 -> 3 -> 4 -> 5 -> 6 -> 7 -> 8 -> 9 -> 10 lvl 1 :1 -> 2 -> 4 -> 6 -> 9 lvl 2 :1 -> 6 -> 9 lvl 3 :1 I use CLion.
Code:
main:
#include <iostream> #include "SkipList.h" int main() { SkipList list{4, 1/4.0}; for (int i = 0; i < 10; i++) { list.push(i + 1); list.out(); } //list.out(); } SkipList.h:
// // Created by nail1 on 09.08.2018. // #ifndef INC_18_11_SKIPLIST_H #define INC_18_11_SKIPLIST_H struct intList { int value; intList* next {nullptr}; }; class SkipList { intList** lvls; int numb_lvls; double p; void pushInLvl(int numb, int val); void findPlace(intList **prev, intList **next, int numb, int val); public: SkipList(int numb, double pp) : numb_lvls{numb}, p{pp} {lvls = new intList*[numb]{nullptr};} void push(int val); void out(); }; #endif //INC_18_11_SKIPLIST_H SkipList.cpp:
// // Created by nail1 on 09.08.2018. // #include "SkipList.h" #include <cstdlib> #include <ctime> #include <iostream> void SkipList::push(int val) { for (int i = 0; i < numb_lvls; i++) { srand(time(NULL)); double rand_numb = ( rand() % 101 ) / 100.0; if (i == 0 || !lvls[i] || rand_numb < p) pushInLvl(i, val); else return; } } void SkipList::pushInLvl(int numb, int val) { intList* prev{nullptr}; intList* next{nullptr}; findPlace(&prev, &next, numb, val); intList* newMemb = new intList{val, nullptr}; if (!prev && !next) { lvls[numb] = newMemb; return; } else if (!prev) { newMemb->next = next; lvls[numb] = newMemb; return; } else if (!next) { prev->next = newMemb; return; } else if (prev && next) { newMemb->next = next; prev->next = newMemb; return; } } void SkipList::findPlace(intList **prev, intList **next, int numb, int val) { *prev = nullptr; *next = nullptr; intList* curLvl{lvls[numb]}; if (!curLvl) return; else if(val < curLvl->value) { *next = curLvl; return; } else { *prev = curLvl; *next = curLvl->next; while (*next && (*next)->value < val) { *prev = *next; *next = (*next)->next; } } } void SkipList::out() { for (int i = 0; i < numb_lvls; i++) { std::cout << "lvl " << i << " :"; intList* curLvl = lvls[i]; while(curLvl) { std::cout << curLvl->value; if (curLvl->next) std::cout << " -> "; curLvl = curLvl->next; } std::cout << std::endl; } }