From d11e8cb40a11415ac82888033977d23d52b3c8b5 Mon Sep 17 00:00:00 2001 From: enqidu Date: Tue, 7 Jul 2020 13:30:42 +0400 Subject: [PATCH 01/38] added skip_list.cpp --- data_structures/skip_list.cpp | 185 ++++++++++++++++++++++++++++++++++ 1 file changed, 185 insertions(+) create mode 100644 data_structures/skip_list.cpp diff --git a/data_structures/skip_list.cpp b/data_structures/skip_list.cpp new file mode 100644 index 000000000..8b6ec1f70 --- /dev/null +++ b/data_structures/skip_list.cpp @@ -0,0 +1,185 @@ +/** + * A skip list is a data structure that is used for storing a sorted list of items with a + * help of hierarchy of linked lists that connect increasingly sparse subsequences of the items + * + * References used: GeeksForGeeks, https://iq.opengenus.org/skip-list/ Pseudo Code, https://ideone.com/XnXIFl from CodeForces. +*/ + +#include +#include +#include +#include +using namespace std; + +#define MAXLVL 2 +#define P 0.5 + + +/** + * Node structure [Key][Node*, Node*...] +*/ +class Node { +public: + int key; + void* value; + /*Forward Array*/ + vector forward; + Node(int key, int level, void* value); +}; + + +Node::Node(int key, int level, void* value) { + this->key = key; + + /*Initialization of forward vector*/ + for (int i = 0; i < sizeof(Node*)*(level+1); i++){ + forward.push_back(NULL); + } +}; + +// Class for Skip list +class SkipList { + int level; + Node *header; +public: + SkipList(); + int randomLevel(); + void insertElement(int, void*); + void deleteElement(int); + void* searchElement(int); + void displayList(); +}; + +SkipList::SkipList() { + level = 0; + /* Header initialization*/ + header = new Node(-1, MAXLVL, NULL); +}; + + +/** + * Returns random level for skip list; +*/ +int SkipList::randomLevel() { + int lvl = 0; + while(rand()%2 < P && lvl < MAXLVL) lvl++; + return lvl; +}; + + +// Insert given key in skip list +void SkipList::insertElement(int key, void* value) { + printf("Inserting %d key ... ", key); + Node *x = header; + Node *update[MAXLVL+1]; + memset(update, 0, sizeof(Node*)*(MAXLVL+1)); + + + for(int i = level; i >= 0; i--) { + while(x->forward[i] != NULL && x->forward[i]->key < key) x = x->forward[i]; + update[i] = x; + } + + x = x->forward[0]; + + bool doesnt_exist = (x == NULL || x->key != key); + if (doesnt_exist) { + int rlevel = randomLevel(); + + if(rlevel > level) { + for(int i=level+1;iforward[i] = update[i]->forward[i]; + update[i]->forward[i] = n; + } + printf(" Inserted\n"); + } else { + printf("Exists\n"); + } +}; + +// Delete element from skip list +void SkipList::deleteElement(int key) +{ + Node *x = header; + + Node *update[MAXLVL+1]; + memset(update, 0, sizeof(Node*)*(MAXLVL+1)); + + for(int i = level; i >= 0; i--) { + while(x->forward[i] != NULL && x->forward[i]->key < key) x = x->forward[i]; + update[i] = x; + } + + x = x->forward[0]; + + bool doesnt_exist = (x == NULL || x->key != key); + + if(!doesnt_exist) { + for(int i=0;i<=level;i++) { + if(update[i]->forward[i] != x) break; + update[i]->forward[i] = x->forward[i]; + } + /*Remove empty levels*/ + while(level>0 && header->forward[level] == 0) level--; + printf("Deleted\n"); + } else { + printf("Doesnt Exists\n"); + } +}; + + +/** + * Searching element in skip list structure +*/ +void* SkipList::searchElement(int key) { + Node *x = header; + printf("Searching for %d\n", key); + + for(int i = level; i >= 0; i--) { + while(x->forward[i] && x->forward[i]->key < key) x = x->forward[i]; + } + + x = x->forward[0]; + if(x && x->key == key){ + printf("FOUND\n"); + return x->value; + } else { + printf("NOT FOUND\n"); + return NULL; + } +}; + +// Display skip list level wise +void SkipList::displayList() { + printf("----SKIP LIST STRUCTURE----\n"); + for(int i=0; i <= level; i++) { + Node *node = header->forward[i]; + printf("Level %d: ", i); + while(node != NULL) { + printf("%d ", node->key); + node = node->forward[i]; + } + printf("\n"); + } +}; + +int main() +{ + srand((unsigned)time(0)); + + SkipList lst; + + for (int j = 0; j < (1 << (MAXLVL+1)); j++){ + int k = (rand() % (1 << (MAXLVL+1) + 1)); + lst.insertElement(k, &j); + } + + lst.displayList(); +} \ No newline at end of file From ec04afc54fccb6ff4c2f5fe32833e0116ac174b3 Mon Sep 17 00:00:00 2001 From: enqidu Date: Tue, 7 Jul 2020 13:34:13 +0400 Subject: [PATCH 02/38] added skip-list --- data_structures/skip_list.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/data_structures/skip_list.cpp b/data_structures/skip_list.cpp index 8b6ec1f70..31e6d06f4 100644 --- a/data_structures/skip_list.cpp +++ b/data_structures/skip_list.cpp @@ -2,7 +2,7 @@ * A skip list is a data structure that is used for storing a sorted list of items with a * help of hierarchy of linked lists that connect increasingly sparse subsequences of the items * - * References used: GeeksForGeeks, https://iq.opengenus.org/skip-list/ Pseudo Code, https://ideone.com/XnXIFl from CodeForces. + * References used: GeeksForGeeks skip list code, https://iq.opengenus.org/skip-list/ Pseudo Code. */ #include @@ -104,7 +104,7 @@ void SkipList::insertElement(int key, void* value) { } }; -// Delete element from skip list + void SkipList::deleteElement(int key) { Node *x = header; From 94338f527bcd26191ed9136722cb7fba985c4233 Mon Sep 17 00:00:00 2001 From: enqidu Date: Tue, 7 Jul 2020 13:43:27 +0400 Subject: [PATCH 03/38] skip_list --- data_structures/skip_list.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/data_structures/skip_list.cpp b/data_structures/skip_list.cpp index 31e6d06f4..603d1f2c3 100644 --- a/data_structures/skip_list.cpp +++ b/data_structures/skip_list.cpp @@ -9,10 +9,12 @@ #include #include #include -using namespace std; #define MAXLVL 2 #define P 0.5 + +using std::endl; +using std::vector; /** From 2c6b8c3bf74d2875def9d296e8bac7adcf45ecbe Mon Sep 17 00:00:00 2001 From: enqidu Date: Tue, 7 Jul 2020 13:46:52 +0400 Subject: [PATCH 04/38] skip_list --- data_structures/skip_list.cpp | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/data_structures/skip_list.cpp b/data_structures/skip_list.cpp index 603d1f2c3..bae1a7bbe 100644 --- a/data_structures/skip_list.cpp +++ b/data_structures/skip_list.cpp @@ -27,7 +27,7 @@ public: /*Forward Array*/ vector forward; Node(int key, int level, void* value); -}; +} Node::Node(int key, int level, void* value) { @@ -37,7 +37,7 @@ Node::Node(int key, int level, void* value) { for (int i = 0; i < sizeof(Node*)*(level+1); i++){ forward.push_back(NULL); } -}; +} // Class for Skip list class SkipList { @@ -50,14 +50,13 @@ public: void deleteElement(int); void* searchElement(int); void displayList(); -}; +} SkipList::SkipList() { level = 0; /* Header initialization*/ header = new Node(-1, MAXLVL, NULL); -}; - +} /** * Returns random level for skip list; @@ -66,7 +65,7 @@ int SkipList::randomLevel() { int lvl = 0; while(rand()%2 < P && lvl < MAXLVL) lvl++; return lvl; -}; +} // Insert given key in skip list @@ -104,8 +103,7 @@ void SkipList::insertElement(int key, void* value) { } else { printf("Exists\n"); } -}; - +} void SkipList::deleteElement(int key) { @@ -134,7 +132,7 @@ void SkipList::deleteElement(int key) } else { printf("Doesnt Exists\n"); } -}; +} /** @@ -156,7 +154,7 @@ void* SkipList::searchElement(int key) { printf("NOT FOUND\n"); return NULL; } -}; +} // Display skip list level wise void SkipList::displayList() { @@ -170,10 +168,9 @@ void SkipList::displayList() { } printf("\n"); } -}; +} -int main() -{ +int main() { srand((unsigned)time(0)); SkipList lst; @@ -184,4 +181,5 @@ int main() } lst.displayList(); + return 0; } \ No newline at end of file From f13964cab2546754e08e61eda061a260473eb7e5 Mon Sep 17 00:00:00 2001 From: enqidu Date: Tue, 7 Jul 2020 14:04:44 +0400 Subject: [PATCH 05/38] skip-list --- data_structures/skip_list.cpp | 33 ++++++++++++++++++--------------- 1 file changed, 18 insertions(+), 15 deletions(-) diff --git a/data_structures/skip_list.cpp b/data_structures/skip_list.cpp index bae1a7bbe..19fdc6276 100644 --- a/data_structures/skip_list.cpp +++ b/data_structures/skip_list.cpp @@ -9,12 +9,12 @@ #include #include #include +// using namespace std; +using std::vector; +using std::endl; #define MAXLVL 2 #define P 0.5 - -using std::endl; -using std::vector; /** @@ -27,7 +27,7 @@ public: /*Forward Array*/ vector forward; Node(int key, int level, void* value); -} +}; Node::Node(int key, int level, void* value) { @@ -37,7 +37,7 @@ Node::Node(int key, int level, void* value) { for (int i = 0; i < sizeof(Node*)*(level+1); i++){ forward.push_back(NULL); } -} +}; // Class for Skip list class SkipList { @@ -50,13 +50,14 @@ public: void deleteElement(int); void* searchElement(int); void displayList(); -} +}; SkipList::SkipList() { level = 0; /* Header initialization*/ header = new Node(-1, MAXLVL, NULL); -} +}; + /** * Returns random level for skip list; @@ -65,7 +66,7 @@ int SkipList::randomLevel() { int lvl = 0; while(rand()%2 < P && lvl < MAXLVL) lvl++; return lvl; -} +}; // Insert given key in skip list @@ -103,7 +104,8 @@ void SkipList::insertElement(int key, void* value) { } else { printf("Exists\n"); } -} +}; + void SkipList::deleteElement(int key) { @@ -132,7 +134,7 @@ void SkipList::deleteElement(int key) } else { printf("Doesnt Exists\n"); } -} +}; /** @@ -154,7 +156,7 @@ void* SkipList::searchElement(int key) { printf("NOT FOUND\n"); return NULL; } -} +}; // Display skip list level wise void SkipList::displayList() { @@ -168,9 +170,10 @@ void SkipList::displayList() { } printf("\n"); } -} +}; -int main() { +int main() +{ srand((unsigned)time(0)); SkipList lst; @@ -181,5 +184,5 @@ int main() { } lst.displayList(); - return 0; -} \ No newline at end of file + +} From 2fb95a2bf3ba4dd411dd1123a412e28e4ae9560a Mon Sep 17 00:00:00 2001 From: enqidu Date: Tue, 7 Jul 2020 14:29:08 +0400 Subject: [PATCH 06/38] skip_list --- data_structures/skip_list.cpp | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/data_structures/skip_list.cpp b/data_structures/skip_list.cpp index 19fdc6276..723958866 100644 --- a/data_structures/skip_list.cpp +++ b/data_structures/skip_list.cpp @@ -37,7 +37,7 @@ Node::Node(int key, int level, void* value) { for (int i = 0; i < sizeof(Node*)*(level+1); i++){ forward.push_back(NULL); } -}; +} // Class for Skip list class SkipList { @@ -50,13 +50,13 @@ public: void deleteElement(int); void* searchElement(int); void displayList(); -}; +}; SkipList::SkipList() { level = 0; /* Header initialization*/ header = new Node(-1, MAXLVL, NULL); -}; +} /** @@ -64,9 +64,10 @@ SkipList::SkipList() { */ int SkipList::randomLevel() { int lvl = 0; - while(rand()%2 < P && lvl < MAXLVL) lvl++; + thread_local unsigned int seed = time(NULL); + while(rand_r(&seed)%2 < P && lvl < MAXLVL) lvl++; return lvl; -}; +} // Insert given key in skip list @@ -104,7 +105,7 @@ void SkipList::insertElement(int key, void* value) { } else { printf("Exists\n"); } -}; +} void SkipList::deleteElement(int key) @@ -134,7 +135,7 @@ void SkipList::deleteElement(int key) } else { printf("Doesnt Exists\n"); } -}; +} /** @@ -156,7 +157,7 @@ void* SkipList::searchElement(int key) { printf("NOT FOUND\n"); return NULL; } -}; +} // Display skip list level wise void SkipList::displayList() { @@ -170,16 +171,17 @@ void SkipList::displayList() { } printf("\n"); } -}; +} int main() { - srand((unsigned)time(0)); + thread_local unsigned int seed = time(NULL); + SkipList lst; for (int j = 0; j < (1 << (MAXLVL+1)); j++){ - int k = (rand() % (1 << (MAXLVL+1) + 1)); + int k = (rand_r(&seed) % (1 << (MAXLVL+1) + 1)); lst.insertElement(k, &j); } From 420915fa0ddff92b6be4922f540c651136f9f6a6 Mon Sep 17 00:00:00 2001 From: enqidu Date: Tue, 7 Jul 2020 14:48:30 +0400 Subject: [PATCH 07/38] skip_list --- data_structures/skip_list.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/data_structures/skip_list.cpp b/data_structures/skip_list.cpp index 723958866..550a5c9d3 100644 --- a/data_structures/skip_list.cpp +++ b/data_structures/skip_list.cpp @@ -9,6 +9,8 @@ #include #include #include +#include +#include // using namespace std; using std::vector; using std::endl; @@ -58,6 +60,8 @@ SkipList::SkipList() { header = new Node(-1, MAXLVL, NULL); } + + /** * Returns random level for skip list; @@ -187,4 +191,6 @@ int main() lst.displayList(); + + } From 910180ff214ae669eb0a9ec6a923a7d00755d746 Mon Sep 17 00:00:00 2001 From: enqidu Date: Tue, 7 Jul 2020 14:54:44 +0400 Subject: [PATCH 08/38] skip_list --- data_structures/skip_list.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/data_structures/skip_list.cpp b/data_structures/skip_list.cpp index 550a5c9d3..3b4ba500f 100644 --- a/data_structures/skip_list.cpp +++ b/data_structures/skip_list.cpp @@ -11,6 +11,8 @@ #include #include #include +#include + // using namespace std; using std::vector; using std::endl; From 8e99383dbf8f373fc7a99fd2db8187f3f88441f4 Mon Sep 17 00:00:00 2001 From: enqidu Date: Tue, 7 Jul 2020 15:13:01 +0400 Subject: [PATCH 09/38] skip_list --- data_structures/skip_list.cpp | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/data_structures/skip_list.cpp b/data_structures/skip_list.cpp index 3b4ba500f..fe5820b43 100644 --- a/data_structures/skip_list.cpp +++ b/data_structures/skip_list.cpp @@ -70,8 +70,7 @@ SkipList::SkipList() { */ int SkipList::randomLevel() { int lvl = 0; - thread_local unsigned int seed = time(NULL); - while(rand_r(&seed)%2 < P && lvl < MAXLVL) lvl++; + while((float)rand()/RAND_MAX < P && lvl < MAXLVL) lvl++; return lvl; } @@ -181,13 +180,12 @@ void SkipList::displayList() { int main() { - thread_local unsigned int seed = time(NULL); + srand((unsigned)time(0)); - SkipList lst; for (int j = 0; j < (1 << (MAXLVL+1)); j++){ - int k = (rand_r(&seed) % (1 << (MAXLVL+1) + 1)); + int k = (rand()% (1 << (MAXLVL+1) + 1)); lst.insertElement(k, &j); } From 2fc0d5bffeaff3845fd8b3ca774b0f9f50cc2299 Mon Sep 17 00:00:00 2001 From: enqidu Date: Tue, 7 Jul 2020 16:40:47 +0400 Subject: [PATCH 10/38] skip-list corrected --- data_structures/skip_list.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/data_structures/skip_list.cpp b/data_structures/skip_list.cpp index fe5820b43..69836e13a 100644 --- a/data_structures/skip_list.cpp +++ b/data_structures/skip_list.cpp @@ -180,12 +180,12 @@ void SkipList::displayList() { int main() { - srand((unsigned)time(0)); + std::srand(time(nullptr)); SkipList lst; for (int j = 0; j < (1 << (MAXLVL+1)); j++){ - int k = (rand()% (1 << (MAXLVL+1) + 1)); + int k = (std::rand()% (1 << (MAXLVL+1) + 1)); lst.insertElement(k, &j); } From ba65d559c5912861bad589e7832becdf321bc01f Mon Sep 17 00:00:00 2001 From: enqidu Date: Tue, 7 Jul 2020 16:51:47 +0400 Subject: [PATCH 11/38] skip-list documentation-polish --- data_structures/skip_list.cpp | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/data_structures/skip_list.cpp b/data_structures/skip_list.cpp index 69836e13a..988165db3 100644 --- a/data_structures/skip_list.cpp +++ b/data_structures/skip_list.cpp @@ -70,14 +70,14 @@ SkipList::SkipList() { */ int SkipList::randomLevel() { int lvl = 0; - while((float)rand()/RAND_MAX < P && lvl < MAXLVL) lvl++; + while(static_cast(rand())/RAND_MAX < P && lvl < MAXLVL) lvl++; return lvl; } // Insert given key in skip list void SkipList::insertElement(int key, void* value) { - printf("Inserting %d key ... ", key); + std::cout << "Inserting" << key << "..."; Node *x = header; Node *update[MAXLVL+1]; memset(update, 0, sizeof(Node*)*(MAXLVL+1)); @@ -106,13 +106,14 @@ void SkipList::insertElement(int key, void* value) { n->forward[i] = update[i]->forward[i]; update[i]->forward[i] = n; } - printf(" Inserted\n"); + std::cout << "Inserted" << endl; + } else { - printf("Exists\n"); + std::cout << "Exists" << endl; } } - + /**Delete document by key*/ void SkipList::deleteElement(int key) { Node *x = header; @@ -136,9 +137,9 @@ void SkipList::deleteElement(int key) } /*Remove empty levels*/ while(level>0 && header->forward[level] == 0) level--; - printf("Deleted\n"); + std::cout << "Deleted" << endl; } else { - printf("Doesnt Exists\n"); + std::cout << "Doesn't exist" << endl; } } @@ -148,7 +149,7 @@ void SkipList::deleteElement(int key) */ void* SkipList::searchElement(int key) { Node *x = header; - printf("Searching for %d\n", key); + std::cout << "Searching for " + key << endl; for(int i = level; i >= 0; i--) { while(x->forward[i] && x->forward[i]->key < key) x = x->forward[i]; @@ -156,25 +157,25 @@ void* SkipList::searchElement(int key) { x = x->forward[0]; if(x && x->key == key){ - printf("FOUND\n"); + std::cout << "Found" << endl; return x->value; } else { - printf("NOT FOUND\n"); + std::cout << "Not Found" << endl; return NULL; } } // Display skip list level wise void SkipList::displayList() { - printf("----SKIP LIST STRUCTURE----\n"); + std::cout << "Displaying list:\n" << endl; for(int i=0; i <= level; i++) { Node *node = header->forward[i]; - printf("Level %d: ", i); + std::cout << "Level " << (i) << ": "; while(node != NULL) { - printf("%d ", node->key); + std::cout << node->key << " "; node = node->forward[i]; } - printf("\n"); + std::cout << endl; } } From 5068ddc14d093c2434edcb359fca0d3594dff86c Mon Sep 17 00:00:00 2001 From: enqidu Date: Tue, 7 Jul 2020 16:55:52 +0400 Subject: [PATCH 12/38] skip-list documentation-polish --- data_structures/skip_list.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data_structures/skip_list.cpp b/data_structures/skip_list.cpp index 988165db3..d2ba820f4 100644 --- a/data_structures/skip_list.cpp +++ b/data_structures/skip_list.cpp @@ -70,7 +70,7 @@ SkipList::SkipList() { */ int SkipList::randomLevel() { int lvl = 0; - while(static_cast(rand())/RAND_MAX < P && lvl < MAXLVL) lvl++; + while(static_cast(std::rand())/RAND_MAX < P && lvl < MAXLVL) lvl++; return lvl; } From dcdebae395ae9edbf40461b8a1cd31659ad20526 Mon Sep 17 00:00:00 2001 From: enqidu Date: Tue, 7 Jul 2020 17:24:13 +0400 Subject: [PATCH 13/38] skip-list documentation-polish --- data_structures/skip_list.cpp | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/data_structures/skip_list.cpp b/data_structures/skip_list.cpp index d2ba820f4..782486632 100644 --- a/data_structures/skip_list.cpp +++ b/data_structures/skip_list.cpp @@ -54,7 +54,10 @@ public: void deleteElement(int); void* searchElement(int); void displayList(); + ~SkipList(); }; + + SkipList::SkipList() { level = 0; @@ -63,6 +66,18 @@ SkipList::SkipList() { } +SkipList::~SkipList(){ + delete header; + for(int i=0; i <= level; i++) { + Node *node = header->forward[i]; + Node* temp; + while(node != NULL) { + temp = node; + node = node->forward[i]; + delete temp; + } + } +} /** From f7ab869d90db9666592980e87ce3465f76de2aaf Mon Sep 17 00:00:00 2001 From: enqidu Date: Tue, 7 Jul 2020 18:16:38 +0400 Subject: [PATCH 14/38] skip list update --- data_structures/skip_list.cpp | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/data_structures/skip_list.cpp b/data_structures/skip_list.cpp index 782486632..480e9dedf 100644 --- a/data_structures/skip_list.cpp +++ b/data_structures/skip_list.cpp @@ -7,25 +7,22 @@ #include #include -#include #include #include #include -#include // using namespace std; using std::vector; using std::endl; -#define MAXLVL 2 -#define P 0.5 +#define MAXLVL 2 ///< maximum level of skip list +#define P 0.5 ///< current probability for "coin toss" /** * Node structure [Key][Node*, Node*...] */ -class Node { -public: +struct Node { int key; void* value; /*Forward Array*/ @@ -38,7 +35,7 @@ Node::Node(int key, int level, void* value) { this->key = key; /*Initialization of forward vector*/ - for (int i = 0; i < sizeof(Node*)*(level+1); i++){ + for (int i = 0; i < (level+1); i++){ forward.push_back(NULL); } } @@ -67,7 +64,6 @@ SkipList::SkipList() { SkipList::~SkipList(){ - delete header; for(int i=0; i <= level; i++) { Node *node = header->forward[i]; Node* temp; @@ -77,6 +73,7 @@ SkipList::~SkipList(){ delete temp; } } + delete header; } @@ -201,12 +198,10 @@ int main() SkipList lst; for (int j = 0; j < (1 << (MAXLVL+1)); j++){ - int k = (std::rand()% (1 << (MAXLVL+1) + 1)); + int k = (std::rand()%( 1 << (MAXLVL+2)) + 1); lst.insertElement(k, &j); } lst.displayList(); - - } From fd8affb59d86b90f244adcd3ccb49dc2b1acf09a Mon Sep 17 00:00:00 2001 From: enqidu Date: Tue, 7 Jul 2020 18:20:21 +0400 Subject: [PATCH 15/38] skip_list --- data_structures/skip_list.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data_structures/skip_list.cpp b/data_structures/skip_list.cpp index 480e9dedf..9d829349e 100644 --- a/data_structures/skip_list.cpp +++ b/data_structures/skip_list.cpp @@ -9,7 +9,7 @@ #include #include #include -#include +#include // using namespace std; using std::vector; From 4cebe7c68270e5474e1b0a3c65355157a741b23b Mon Sep 17 00:00:00 2001 From: enqidu Date: Tue, 7 Jul 2020 18:21:12 +0400 Subject: [PATCH 16/38] skip_list --- data_structures/skip_list.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data_structures/skip_list.cpp b/data_structures/skip_list.cpp index 9d829349e..180d9c32d 100644 --- a/data_structures/skip_list.cpp +++ b/data_structures/skip_list.cpp @@ -193,7 +193,7 @@ void SkipList::displayList() { int main() { - std::srand(time(nullptr)); + std::srand(std::time(nullptr)); SkipList lst; From ac0d11977d0b8fcc3396855bed490bfc690b2ad4 Mon Sep 17 00:00:00 2001 From: enqidu Date: Tue, 7 Jul 2020 19:17:37 +0400 Subject: [PATCH 17/38] skip_list --- data_structures/skip_list.cpp | 66 ++++++++++++++++++++++------------- 1 file changed, 41 insertions(+), 25 deletions(-) diff --git a/data_structures/skip_list.cpp b/data_structures/skip_list.cpp index 180d9c32d..c41d3c2e1 100644 --- a/data_structures/skip_list.cpp +++ b/data_structures/skip_list.cpp @@ -2,7 +2,7 @@ * A skip list is a data structure that is used for storing a sorted list of items with a * help of hierarchy of linked lists that connect increasingly sparse subsequences of the items * - * References used: GeeksForGeeks skip list code, https://iq.opengenus.org/skip-list/ Pseudo Code. + * References used: GeeksForGeeks skip list code, https://iq.opengenus.org/skip-list/ Code and PseudoCode. */ #include @@ -15,28 +15,31 @@ using std::vector; using std::endl; -#define MAXLVL 2 ///< maximum level of skip list -#define P 0.5 ///< current probability for "coin toss" +#define MAX_LEVEL 2 ///< maximum level of skip list +#define PROBABILITY 0.5 ///< current probability for "coin toss" /** * Node structure [Key][Node*, Node*...] */ struct Node { - int key; + int key; + /* pointer of value */ void* value; /*Forward Array*/ vector forward; Node(int key, int level, void* value); }; - +/** + * Creates node with provided key, level and value; +*/ Node::Node(int key, int level, void* value) { this->key = key; /*Initialization of forward vector*/ for (int i = 0; i < (level+1); i++){ - forward.push_back(NULL); + forward.push_back(nullptr); } } @@ -55,11 +58,13 @@ public: }; - +/**\ + * Skeep List constructor; +*/ SkipList::SkipList() { level = 0; /* Header initialization*/ - header = new Node(-1, MAXLVL, NULL); + header = new Node(-1, MAX_LEVEL, nullptr); } @@ -67,7 +72,7 @@ SkipList::~SkipList(){ for(int i=0; i <= level; i++) { Node *node = header->forward[i]; Node* temp; - while(node != NULL) { + while(node != nullptr) { temp = node; node = node->forward[i]; delete temp; @@ -82,27 +87,31 @@ SkipList::~SkipList(){ */ int SkipList::randomLevel() { int lvl = 0; - while(static_cast(std::rand())/RAND_MAX < P && lvl < MAXLVL) lvl++; + while(static_cast(std::rand())/RAND_MAX < PROBABILITY && lvl < MAX_LEVEL) lvl++; return lvl; } -// Insert given key in skip list + +/** + * Inserts elements with given key and value; + * It's level is computed by randomLevel() function. +*/ void SkipList::insertElement(int key, void* value) { std::cout << "Inserting" << key << "..."; Node *x = header; - Node *update[MAXLVL+1]; - memset(update, 0, sizeof(Node*)*(MAXLVL+1)); + Node *update[MAX_LEVEL+1]; + memset(update, 0, sizeof(Node*)*(MAX_LEVEL+1)); for(int i = level; i >= 0; i--) { - while(x->forward[i] != NULL && x->forward[i]->key < key) x = x->forward[i]; + while(x->forward[i] != nullptr && x->forward[i]->key < key) x = x->forward[i]; update[i] = x; } x = x->forward[0]; - bool doesnt_exist = (x == NULL || x->key != key); + bool doesnt_exist = (x == nullptr || x->key != key); if (doesnt_exist) { int rlevel = randomLevel(); @@ -130,17 +139,17 @@ void SkipList::deleteElement(int key) { Node *x = header; - Node *update[MAXLVL+1]; - memset(update, 0, sizeof(Node*)*(MAXLVL+1)); + Node *update[MAX_LEVEL+1]; + memset(update, 0, sizeof(Node*)*(MAX_LEVEL+1)); for(int i = level; i >= 0; i--) { - while(x->forward[i] != NULL && x->forward[i]->key < key) x = x->forward[i]; + while(x->forward[i] != nullptr && x->forward[i]->key < key) x = x->forward[i]; update[i] = x; } x = x->forward[0]; - bool doesnt_exist = (x == NULL || x->key != key); + bool doesnt_exist = (x == nullptr || x->key != key); if(!doesnt_exist) { for(int i=0;i<=level;i++) { @@ -173,32 +182,39 @@ void* SkipList::searchElement(int key) { return x->value; } else { std::cout << "Not Found" << endl; - return NULL; + return nullptr; } } -// Display skip list level wise +/** + * Display skip list level wise + */ void SkipList::displayList() { std::cout << "Displaying list:\n" << endl; for(int i=0; i <= level; i++) { Node *node = header->forward[i]; std::cout << "Level " << (i) << ": "; - while(node != NULL) { + while(node != nullptr) { std::cout << node->key << " "; node = node->forward[i]; } std::cout << endl; } } - + + +/** + * Main function: + * Creates and inserts random 2^[number of levels] elements into the skip lists and than displays it + */ int main() { std::srand(std::time(nullptr)); SkipList lst; - for (int j = 0; j < (1 << (MAXLVL+1)); j++){ - int k = (std::rand()%( 1 << (MAXLVL+2)) + 1); + for (int j = 0; j < (1 << (MAX_LEVEL+1)); j++){ + int k = (std::rand()%( 1 << (MAX_LEVEL+2)) + 1); lst.insertElement(k, &j); } From d5b897d40e3354e64c6c1bb1bf91435a2bb769b4 Mon Sep 17 00:00:00 2001 From: enqidu Date: Tue, 7 Jul 2020 19:22:32 +0400 Subject: [PATCH 18/38] improve --- data_structures/skip_list.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/data_structures/skip_list.cpp b/data_structures/skip_list.cpp index c41d3c2e1..5881f5d27 100644 --- a/data_structures/skip_list.cpp +++ b/data_structures/skip_list.cpp @@ -7,8 +7,7 @@ #include #include -#include -#include +#include #include // using namespace std; From ea57ad29cd350a265be297a49bc8c65c8dfcc825 Mon Sep 17 00:00:00 2001 From: enqidu Date: Tue, 7 Jul 2020 19:55:47 +0400 Subject: [PATCH 19/38] improve --- data_structures/skip_list.cpp | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/data_structures/skip_list.cpp b/data_structures/skip_list.cpp index 5881f5d27..eb8e5cd87 100644 --- a/data_structures/skip_list.cpp +++ b/data_structures/skip_list.cpp @@ -23,26 +23,28 @@ using std::endl; */ struct Node { int key; - /* pointer of value */ + //pointer of value void* value; - /*Forward Array*/ + //Forward Array vector forward; Node(int key, int level, void* value); }; /** - * Creates node with provided key, level and value; + * Creates node with provided key, level and value */ Node::Node(int key, int level, void* value) { this->key = key; - /*Initialization of forward vector*/ + //Initialization of forward vector for (int i = 0; i < (level+1); i++){ forward.push_back(nullptr); } } -// Class for Skip list +/** + * SkipList class +*/ class SkipList { int level; Node *header; @@ -57,12 +59,12 @@ public: }; -/**\ - * Skeep List constructor; +/** + * Skeep List constructor */ SkipList::SkipList() { level = 0; - /* Header initialization*/ + // Header initialization header = new Node(-1, MAX_LEVEL, nullptr); } @@ -117,7 +119,7 @@ void SkipList::insertElement(int key, void* value) { if(rlevel > level) { for(int i=level+1;i Date: Tue, 7 Jul 2020 19:58:10 +0400 Subject: [PATCH 20/38] improve --- data_structures/skip_list.cpp | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/data_structures/skip_list.cpp b/data_structures/skip_list.cpp index eb8e5cd87..25a9aae2a 100644 --- a/data_structures/skip_list.cpp +++ b/data_structures/skip_list.cpp @@ -1,4 +1,4 @@ -/** +/* * A skip list is a data structure that is used for storing a sorted list of items with a * help of hierarchy of linked lists that connect increasingly sparse subsequences of the items * @@ -18,7 +18,7 @@ using std::endl; #define PROBABILITY 0.5 ///< current probability for "coin toss" -/** +/* * Node structure [Key][Node*, Node*...] */ struct Node { @@ -30,7 +30,7 @@ struct Node { Node(int key, int level, void* value); }; -/** +/* * Creates node with provided key, level and value */ Node::Node(int key, int level, void* value) { @@ -42,7 +42,7 @@ Node::Node(int key, int level, void* value) { } } -/** +/* * SkipList class */ class SkipList { @@ -59,7 +59,7 @@ public: }; -/** +/* * Skeep List constructor */ SkipList::SkipList() { @@ -83,7 +83,7 @@ SkipList::~SkipList(){ } -/** +/* * Returns random level for skip list; */ int SkipList::randomLevel() { @@ -94,7 +94,7 @@ int SkipList::randomLevel() { -/** +/* * Inserts elements with given key and value; * It's level is computed by randomLevel() function. */ @@ -135,7 +135,9 @@ void SkipList::insertElement(int key, void* value) { } } - /**Delete document by key*/ +/* + * Delete document by key +*/ void SkipList::deleteElement(int key) { Node *x = header; @@ -166,7 +168,7 @@ void SkipList::deleteElement(int key) } -/** +/* * Searching element in skip list structure */ void* SkipList::searchElement(int key) { @@ -187,7 +189,7 @@ void* SkipList::searchElement(int key) { } } -/** +/* * Display skip list level wise */ void SkipList::displayList() { @@ -204,7 +206,7 @@ void SkipList::displayList() { } -/** +/* * Main function: * Creates and inserts random 2^[number of levels] elements into the skip lists and than displays it */ From 662841bac7e69b6414ab09ed9871b63de7b6b65d Mon Sep 17 00:00:00 2001 From: enqidu Date: Tue, 7 Jul 2020 19:59:54 +0400 Subject: [PATCH 21/38] improve --- data_structures/skip_list.cpp | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/data_structures/skip_list.cpp b/data_structures/skip_list.cpp index 25a9aae2a..729ce1d80 100644 --- a/data_structures/skip_list.cpp +++ b/data_structures/skip_list.cpp @@ -18,7 +18,7 @@ using std::endl; #define PROBABILITY 0.5 ///< current probability for "coin toss" -/* +/** * Node structure [Key][Node*, Node*...] */ struct Node { @@ -30,7 +30,7 @@ struct Node { Node(int key, int level, void* value); }; -/* +/** * Creates node with provided key, level and value */ Node::Node(int key, int level, void* value) { @@ -42,7 +42,7 @@ Node::Node(int key, int level, void* value) { } } -/* +/** * SkipList class */ class SkipList { @@ -59,7 +59,7 @@ public: }; -/* +/** * Skeep List constructor */ SkipList::SkipList() { @@ -68,7 +68,9 @@ SkipList::SkipList() { header = new Node(-1, MAX_LEVEL, nullptr); } - +/** + * Destructor for skiplist class +*/ SkipList::~SkipList(){ for(int i=0; i <= level; i++) { Node *node = header->forward[i]; @@ -83,7 +85,7 @@ SkipList::~SkipList(){ } -/* +/** * Returns random level for skip list; */ int SkipList::randomLevel() { @@ -94,7 +96,7 @@ int SkipList::randomLevel() { -/* +/** * Inserts elements with given key and value; * It's level is computed by randomLevel() function. */ @@ -135,7 +137,7 @@ void SkipList::insertElement(int key, void* value) { } } -/* +/** * Delete document by key */ void SkipList::deleteElement(int key) @@ -168,7 +170,7 @@ void SkipList::deleteElement(int key) } -/* +/** * Searching element in skip list structure */ void* SkipList::searchElement(int key) { @@ -206,7 +208,7 @@ void SkipList::displayList() { } -/* +/** * Main function: * Creates and inserts random 2^[number of levels] elements into the skip lists and than displays it */ From 45b21f287116aaffd52fe8b40a9d5104a5ab31e7 Mon Sep 17 00:00:00 2001 From: enqidu Date: Tue, 7 Jul 2020 20:29:37 +0400 Subject: [PATCH 22/38] improve --- data_structures/skip_list.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data_structures/skip_list.cpp b/data_structures/skip_list.cpp index 729ce1d80..1fc9f3e0e 100644 --- a/data_structures/skip_list.cpp +++ b/data_structures/skip_list.cpp @@ -1,4 +1,4 @@ -/* +/** * A skip list is a data structure that is used for storing a sorted list of items with a * help of hierarchy of linked lists that connect increasingly sparse subsequences of the items * From 59a8b3d4a295e7af34437151e0f50c973eb7e77d Mon Sep 17 00:00:00 2001 From: enqidu Date: Wed, 8 Jul 2020 20:43:52 +0400 Subject: [PATCH 23/38] Update data_structures/skip_list.cpp Co-authored-by: David Leal --- data_structures/skip_list.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/data_structures/skip_list.cpp b/data_structures/skip_list.cpp index 1fc9f3e0e..62ae51ea9 100644 --- a/data_structures/skip_list.cpp +++ b/data_structures/skip_list.cpp @@ -210,7 +210,8 @@ void SkipList::displayList() { /** * Main function: - * Creates and inserts random 2^[number of levels] elements into the skip lists and than displays it + * Creates and inserts random 2^[number of levels] + * elements into the skip lists and than displays it */ int main() { From a5ca794aa4e27e6fb5d9c6e591449458ee5b8fe4 Mon Sep 17 00:00:00 2001 From: enqidu Date: Wed, 8 Jul 2020 20:46:50 +0400 Subject: [PATCH 24/38] sk --- data_structures/skip_list.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/data_structures/skip_list.cpp b/data_structures/skip_list.cpp index 1fc9f3e0e..b7aab7882 100644 --- a/data_structures/skip_list.cpp +++ b/data_structures/skip_list.cpp @@ -10,7 +10,6 @@ #include #include -// using namespace std; using std::vector; using std::endl; @@ -23,9 +22,9 @@ using std::endl; */ struct Node { int key; - //pointer of value + // pointer of value void* value; - //Forward Array + // Forward Array vector forward; Node(int key, int level, void* value); }; From bba0db36ec5aa125fa4acdb35191e8348aaa670b Mon Sep 17 00:00:00 2001 From: enqidu Date: Wed, 8 Jul 2020 20:47:43 +0400 Subject: [PATCH 25/38] sk --- data_structures/skip_list.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/data_structures/skip_list.cpp b/data_structures/skip_list.cpp index 3e13ee696..922c5a1e3 100644 --- a/data_structures/skip_list.cpp +++ b/data_structures/skip_list.cpp @@ -120,7 +120,7 @@ void SkipList::insertElement(int key, void* value) { if(rlevel > level) { for(int i=level+1;iforward[i] != x) break; update[i]->forward[i] = x->forward[i]; } - /*Remove empty levels*/ + /* Remove empty levels*/ while(level>0 && header->forward[level] == 0) level--; std::cout << "Deleted" << endl; } else { From ab1ddb364f3116e08bd52f6424f5cfbaca484157 Mon Sep 17 00:00:00 2001 From: enqidu Date: Fri, 10 Jul 2020 20:39:33 +0400 Subject: [PATCH 26/38] documentation --- data_structures/skip_list.cpp | 34 ++++++++++++++++++++++++---------- 1 file changed, 24 insertions(+), 10 deletions(-) diff --git a/data_structures/skip_list.cpp b/data_structures/skip_list.cpp index 922c5a1e3..dc9b06776 100644 --- a/data_structures/skip_list.cpp +++ b/data_structures/skip_list.cpp @@ -13,8 +13,8 @@ using std::vector; using std::endl; -#define MAX_LEVEL 2 ///< maximum level of skip list -#define PROBABILITY 0.5 ///< current probability for "coin toss" +#define MAX_LEVEL 2 ///< Maximum level of skip list +#define PROBABILITY 0.5 ///< Current probability for "coin toss" /** @@ -24,13 +24,18 @@ struct Node { int key; // pointer of value void* value; - // Forward Array + // Forward Array points to the neighbour (right) + // nodes of the given one in all levels vector forward; + // Constructor of the node Node(int key, int level, void* value); }; /** * Creates node with provided key, level and value + * @param key is number that is used for comparision + * @param level is the maximum level node's going to added + * */ Node::Node(int key, int level, void* value) { this->key = key; @@ -42,10 +47,12 @@ Node::Node(int key, int level, void* value) { } /** - * SkipList class + * SkipList class implementation with basic methods */ class SkipList { + // Maximum level of the skiplist int level; + // Pointer to the header node Node *header; public: SkipList(); @@ -59,7 +66,8 @@ public: /** - * Skeep List constructor + * Skeep List constructor. Initializes header, start + * Node for searching in the list */ SkipList::SkipList() { level = 0; @@ -85,7 +93,9 @@ SkipList::~SkipList(){ /** - * Returns random level for skip list; + * Returns random level of the skip list. + * Every higher level is 2 times less likely. + * @return lvl: random level for skip list; */ int SkipList::randomLevel() { int lvl = 0; @@ -98,6 +108,8 @@ int SkipList::randomLevel() { /** * Inserts elements with given key and value; * It's level is computed by randomLevel() function. + * @param key is number that is used for comparision + * @param value pointer to a value, that can be any type */ void SkipList::insertElement(int key, void* value) { std::cout << "Inserting" << key << "..."; @@ -137,10 +149,10 @@ void SkipList::insertElement(int key, void* value) { } /** - * Delete document by key + * Deletes an element by key and prints if has been removed successfully + * @param key is number that is used for comparision. */ -void SkipList::deleteElement(int key) -{ +void SkipList::deleteElement(int key) { Node *x = header; Node *update[MAX_LEVEL+1]; @@ -171,6 +183,8 @@ void SkipList::deleteElement(int key) /** * Searching element in skip list structure + * @param key is number that is used for comparision + * @return pointer to the value of the node */ void* SkipList::searchElement(int key) { Node *x = header; @@ -191,7 +205,7 @@ void* SkipList::searchElement(int key) { } /* - * Display skip list level wise + * Display skip list level */ void SkipList::displayList() { std::cout << "Displaying list:\n" << endl; From d59005678d7b2f294df26c088842ab3e44f85f31 Mon Sep 17 00:00:00 2001 From: enqidu Date: Fri, 10 Jul 2020 20:40:00 +0400 Subject: [PATCH 27/38] documentation --- data_structures/skip_list.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/data_structures/skip_list.cpp b/data_structures/skip_list.cpp index dc9b06776..80717050a 100644 --- a/data_structures/skip_list.cpp +++ b/data_structures/skip_list.cpp @@ -35,7 +35,6 @@ struct Node { * Creates node with provided key, level and value * @param key is number that is used for comparision * @param level is the maximum level node's going to added - * */ Node::Node(int key, int level, void* value) { this->key = key; From a90dcc5f66126049e91e0fa3835a55f6afb7d9fe Mon Sep 17 00:00:00 2001 From: enqidu Date: Fri, 10 Jul 2020 21:10:21 +0400 Subject: [PATCH 28/38] parameters --- data_structures/skip_list.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/data_structures/skip_list.cpp b/data_structures/skip_list.cpp index 80717050a..37839dfdb 100644 --- a/data_structures/skip_list.cpp +++ b/data_structures/skip_list.cpp @@ -1,8 +1,12 @@ /** + * @file skip_list.cpp + * @brief data struccture for fast searching and insertion (O(log(n))) + * @details * A skip list is a data structure that is used for storing a sorted list of items with a - * help of hierarchy of linked lists that connect increasingly sparse subsequences of the items + * help of hierarchy of linked lists that connect increasingly sparse subsequences of the items * - * References used: GeeksForGeeks skip list code, https://iq.opengenus.org/skip-list/ Code and PseudoCode. + * References used: GeeksForGeeks skip list code, https://iq.opengenus.org/skip-list/ PseudoCode and Code + * . */ #include From 2fecf67a365b9329036d623467dde998903ead98 Mon Sep 17 00:00:00 2001 From: enqidu Date: Fri, 10 Jul 2020 21:11:20 +0400 Subject: [PATCH 29/38] parameters --- data_structures/skip_list.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/data_structures/skip_list.cpp b/data_structures/skip_list.cpp index 37839dfdb..6159506a0 100644 --- a/data_structures/skip_list.cpp +++ b/data_structures/skip_list.cpp @@ -6,6 +6,7 @@ * help of hierarchy of linked lists that connect increasingly sparse subsequences of the items * * References used: GeeksForGeeks skip list code, https://iq.opengenus.org/skip-list/ PseudoCode and Code + * @author enqidu * . */ From b1b3b310a403398d279cbe6c619d109068fe11e1 Mon Sep 17 00:00:00 2001 From: enqidu Date: Fri, 10 Jul 2020 21:27:22 +0400 Subject: [PATCH 30/38] Update data_structures/skip_list.cpp Co-authored-by: Krishna Vedala <7001608+kvedala@users.noreply.github.com> --- data_structures/skip_list.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data_structures/skip_list.cpp b/data_structures/skip_list.cpp index 6159506a0..515c6d138 100644 --- a/data_structures/skip_list.cpp +++ b/data_structures/skip_list.cpp @@ -5,7 +5,7 @@ * A skip list is a data structure that is used for storing a sorted list of items with a * help of hierarchy of linked lists that connect increasingly sparse subsequences of the items * - * References used: GeeksForGeeks skip list code, https://iq.opengenus.org/skip-list/ PseudoCode and Code + * References used: [GeeksForGeek](https://www.geeksforgeeks.org/skip-list/), [OpenGenus](https://iq.opengenus.org/skip-list) for PseudoCode and Code * @author enqidu * . */ From 5d225aba874d4b74021c1865f62148517a869f30 Mon Sep 17 00:00:00 2001 From: enqidu Date: Fri, 10 Jul 2020 21:27:35 +0400 Subject: [PATCH 31/38] Update data_structures/skip_list.cpp Co-authored-by: Krishna Vedala <7001608+kvedala@users.noreply.github.com> --- data_structures/skip_list.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data_structures/skip_list.cpp b/data_structures/skip_list.cpp index 515c6d138..cefd23403 100644 --- a/data_structures/skip_list.cpp +++ b/data_structures/skip_list.cpp @@ -6,7 +6,7 @@ * help of hierarchy of linked lists that connect increasingly sparse subsequences of the items * * References used: [GeeksForGeek](https://www.geeksforgeeks.org/skip-list/), [OpenGenus](https://iq.opengenus.org/skip-list) for PseudoCode and Code - * @author enqidu + * @author [enqidu](https://github.com/enqidu) * . */ From af49a02ed85b944d88c13393c0ecd2cd30f5a0d7 Mon Sep 17 00:00:00 2001 From: enqidu Date: Fri, 10 Jul 2020 21:27:51 +0400 Subject: [PATCH 32/38] Update data_structures/skip_list.cpp Co-authored-by: Krishna Vedala <7001608+kvedala@users.noreply.github.com> --- data_structures/skip_list.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data_structures/skip_list.cpp b/data_structures/skip_list.cpp index cefd23403..6e6d78e13 100644 --- a/data_structures/skip_list.cpp +++ b/data_structures/skip_list.cpp @@ -1,6 +1,6 @@ /** * @file skip_list.cpp - * @brief data struccture for fast searching and insertion (O(log(n))) + * @brief Data structure for fast searching and insertion in \f$O(\log n)\f$ time * @details * A skip list is a data structure that is used for storing a sorted list of items with a * help of hierarchy of linked lists that connect increasingly sparse subsequences of the items From a707d710b58e5921d7f7131932f48f7e7860e7bd Mon Sep 17 00:00:00 2001 From: enqidu Date: Sun, 12 Jul 2020 19:24:46 +0400 Subject: [PATCH 33/38] update --- data_structures/skip_list.cpp | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/data_structures/skip_list.cpp b/data_structures/skip_list.cpp index 6159506a0..f0a17815a 100644 --- a/data_structures/skip_list.cpp +++ b/data_structures/skip_list.cpp @@ -26,12 +26,9 @@ using std::endl; * Node structure [Key][Node*, Node*...] */ struct Node { - int key; - // pointer of value - void* value; - // Forward Array points to the neighbour (right) - // nodes of the given one in all levels - vector forward; + int key; ///< key integer + void* value; ///< pointer of value + vector forward; ///< nodes of the given one in all levels // Constructor of the node Node(int key, int level, void* value); }; @@ -54,10 +51,8 @@ Node::Node(int key, int level, void* value) { * SkipList class implementation with basic methods */ class SkipList { - // Maximum level of the skiplist - int level; - // Pointer to the header node - Node *header; + int level; ///< Maximum level of the skiplist + Node *header; ///< Pointer to the header node public: SkipList(); int randomLevel(); From f970ce361cd1f17e289068a1e36c19eb362db1a0 Mon Sep 17 00:00:00 2001 From: Krishna Vedala <7001608+kvedala@users.noreply.github.com> Date: Sun, 12 Jul 2020 17:00:27 -0400 Subject: [PATCH 34/38] tidied up code based on error reports by clang-tidy --- data_structures/skip_list.cpp | 422 +++++++++++++++++----------------- 1 file changed, 208 insertions(+), 214 deletions(-) diff --git a/data_structures/skip_list.cpp b/data_structures/skip_list.cpp index 373b93dad..d7982f866 100644 --- a/data_structures/skip_list.cpp +++ b/data_structures/skip_list.cpp @@ -1,241 +1,235 @@ /** * @file skip_list.cpp - * @brief Data structure for fast searching and insertion in \f$O(\log n)\f$ time + * @brief Data structure for fast searching and insertion in \f$O(\log n)\f$ + * time * @details - * A skip list is a data structure that is used for storing a sorted list of items with a - * help of hierarchy of linked lists that connect increasingly sparse subsequences of the items - * - * References used: [GeeksForGeek](https://www.geeksforgeeks.org/skip-list/), [OpenGenus](https://iq.opengenus.org/skip-list) for PseudoCode and Code + * A skip list is a data structure that is used for storing a sorted list of + * items with a help of hierarchy of linked lists that connect increasingly + * sparse subsequences of the items + * + * References used: [GeeksForGeek](https://www.geeksforgeeks.org/skip-list/), + * [OpenGenus](https://iq.opengenus.org/skip-list) for PseudoCode and Code * @author [enqidu](https://github.com/enqidu) - * . -*/ + * @author [Krishna Vedala](https://github.com/kvedala) + */ -#include -#include +#include #include -#include +#include +#include +#include +#include -using std::vector; -using std::endl; - -#define MAX_LEVEL 2 ///< Maximum level of skip list -#define PROBABILITY 0.5 ///< Current probability for "coin toss" - +/** \namespace data_structure + * \brief Data-structure algorithms + */ +namespace data_structure { +constexpr int MAX_LEVEL = 2; ///< Maximum level of skip list +constexpr float PROBABILITY = 0.5; ///< Current probability for "coin toss" /** * Node structure [Key][Node*, Node*...] -*/ -struct Node { - int key; ///< key integer - void* value; ///< pointer of value - vector forward; ///< nodes of the given one in all levels - // Constructor of the node - Node(int key, int level, void* value); + */ +struct Node { + int key; ///< key integer + void* value; ///< pointer of value + std::vector> + forward; ///< nodes of the given one in all levels + + /** + * Creates node with provided key, level and value + * @param key is number that is used for comparision + * @param level is the maximum level node's going to added + */ + Node(int key, int level, void* value = nullptr) : key(key) { + // Initialization of forward vector + for (int i = 0; i < (level + 1); i++) { + forward.push_back(nullptr); + } + } }; -/** - * Creates node with provided key, level and value - * @param key is number that is used for comparision - * @param level is the maximum level node's going to added -*/ -Node::Node(int key, int level, void* value) { - this->key = key; - - //Initialization of forward vector - for (int i = 0; i < (level+1); i++){ - forward.push_back(nullptr); - } -} - /** * SkipList class implementation with basic methods -*/ -class SkipList { - int level; ///< Maximum level of the skiplist - Node *header; ///< Pointer to the header node -public: - SkipList(); - int randomLevel(); - void insertElement(int, void*); - void deleteElement(int); - void* searchElement(int); - void displayList(); - ~SkipList(); + */ +class SkipList { + int level; ///< Maximum level of the skiplist + std::shared_ptr header; ///< Pointer to the header node + + public: + /** + * Skip List constructor. Initializes header, start + * Node for searching in the list + */ + SkipList() { + level = 0; + // Header initialization + header = std::shared_ptr(new Node(-1, MAX_LEVEL)); + } + + /** + * Destructor for skiplist class + */ + ~SkipList() { + for (int i = 0; i <= level; i++) { + std::shared_ptr node = header->forward[i]; + std::shared_ptr temp; + while (node != nullptr) { + temp = node; + node = node->forward[i]; + temp.reset(); + } + } + header.reset(); + } + + /** + * Returns random level of the skip list. + * Every higher level is 2 times less likely. + * @return random level for skip list + */ + int randomLevel() { + int lvl = 0; + while (static_cast(std::rand() / RAND_MAX) < PROBABILITY && + lvl < MAX_LEVEL) + lvl++; + return lvl; + } + + /** + * Inserts elements with given key and value; + * It's level is computed by randomLevel() function. + * @param key is number that is used for comparision + * @param value pointer to a value, that can be any type + */ + void insertElement(int key, void* value) { + std::cout << "Inserting" << key << "..."; + std::shared_ptr x = header; + std::array, MAX_LEVEL + 1> update; + update.fill(nullptr); + + for (int i = level; i >= 0; i--) { + while (x->forward[i] != nullptr && x->forward[i]->key < key) + x = x->forward[i]; + update[i] = x; + } + + x = x->forward[0]; + + bool doesnt_exist = (x == nullptr || x->key != key); + if (doesnt_exist) { + int rlevel = randomLevel(); + + if (rlevel > level) { + for (int i = level + 1; i < rlevel + 1; i++) update[i] = header; + + // Update current level + level = rlevel; + } + + std::shared_ptr n = + std::shared_ptr(new Node(key, rlevel, value)); + for (int i = 0; i <= rlevel; i++) { + n->forward[i] = update[i]->forward[i]; + update[i]->forward[i] = n; + } + std::cout << "Inserted" << std::endl; + + } else { + std::cout << "Exists" << std::endl; + } + } + + /** + * Deletes an element by key and prints if has been removed successfully + * @param key is number that is used for comparision. + */ + void deleteElement(int key) { + std::shared_ptr x = header; + + std::array, MAX_LEVEL + 1> update; + update.fill(nullptr); + + for (int i = level; i >= 0; i--) { + while (x->forward[i] != nullptr && x->forward[i]->key < key) + x = x->forward[i]; + update[i] = x; + } + + x = x->forward[0]; + + bool doesnt_exist = (x == nullptr || x->key != key); + + if (!doesnt_exist) { + for (int i = 0; i <= level; i++) { + if (update[i]->forward[i] != x) + break; + update[i]->forward[i] = x->forward[i]; + } + /* Remove empty levels*/ + while (level > 0 && header->forward[level] == nullptr) level--; + std::cout << "Deleted" << std::endl; + } else { + std::cout << "Doesn't exist" << std::endl; + } + } + + /** + * Searching element in skip list structure + * @param key is number that is used for comparision + * @return pointer to the value of the node + */ + void* searchElement(int key) { + std::shared_ptr x = header; + std::cout << "Searching for " << key << std::endl; + + for (int i = level; i >= 0; i--) { + while (x->forward[i] && x->forward[i]->key < key) x = x->forward[i]; + } + + x = x->forward[0]; + if (x && x->key == key) { + std::cout << "Found" << std::endl; + return x->value; + } else { + std::cout << "Not Found" << std::endl; + return nullptr; + } + } + + /* + * Display skip list level + */ + void displayList() { + std::cout << "Displaying list:\n" << std::endl; + for (int i = 0; i <= level; i++) { + std::shared_ptr node = header->forward[i]; + std::cout << "Level " << (i) << ": "; + while (node != nullptr) { + std::cout << node->key << " "; + node = node->forward[i]; + } + std::cout << std::endl; + } + } }; - -/** - * Skeep List constructor. Initializes header, start - * Node for searching in the list -*/ -SkipList::SkipList() { - level = 0; - // Header initialization - header = new Node(-1, MAX_LEVEL, nullptr); -} - -/** - * Destructor for skiplist class -*/ -SkipList::~SkipList(){ - for(int i=0; i <= level; i++) { - Node *node = header->forward[i]; - Node* temp; - while(node != nullptr) { - temp = node; - node = node->forward[i]; - delete temp; - } - } - delete header; -} - - -/** - * Returns random level of the skip list. - * Every higher level is 2 times less likely. - * @return lvl: random level for skip list; -*/ -int SkipList::randomLevel() { - int lvl = 0; - while(static_cast(std::rand())/RAND_MAX < PROBABILITY && lvl < MAX_LEVEL) lvl++; - return lvl; -} - - - -/** - * Inserts elements with given key and value; - * It's level is computed by randomLevel() function. - * @param key is number that is used for comparision - * @param value pointer to a value, that can be any type -*/ -void SkipList::insertElement(int key, void* value) { - std::cout << "Inserting" << key << "..."; - Node *x = header; - Node *update[MAX_LEVEL+1]; - memset(update, 0, sizeof(Node*)*(MAX_LEVEL+1)); - - - for(int i = level; i >= 0; i--) { - while(x->forward[i] != nullptr && x->forward[i]->key < key) x = x->forward[i]; - update[i] = x; - } - - x = x->forward[0]; - - bool doesnt_exist = (x == nullptr || x->key != key); - if (doesnt_exist) { - int rlevel = randomLevel(); - - if(rlevel > level) { - for(int i=level+1;iforward[i] = update[i]->forward[i]; - update[i]->forward[i] = n; - } - std::cout << "Inserted" << endl; - - } else { - std::cout << "Exists" << endl; - } -} - -/** - * Deletes an element by key and prints if has been removed successfully - * @param key is number that is used for comparision. -*/ -void SkipList::deleteElement(int key) { - Node *x = header; - - Node *update[MAX_LEVEL+1]; - memset(update, 0, sizeof(Node*)*(MAX_LEVEL+1)); - - for(int i = level; i >= 0; i--) { - while(x->forward[i] != nullptr && x->forward[i]->key < key) x = x->forward[i]; - update[i] = x; - } - - x = x->forward[0]; - - bool doesnt_exist = (x == nullptr || x->key != key); - - if(!doesnt_exist) { - for(int i=0;i<=level;i++) { - if(update[i]->forward[i] != x) break; - update[i]->forward[i] = x->forward[i]; - } - /* Remove empty levels*/ - while(level>0 && header->forward[level] == 0) level--; - std::cout << "Deleted" << endl; - } else { - std::cout << "Doesn't exist" << endl; - } -} - - -/** - * Searching element in skip list structure - * @param key is number that is used for comparision - * @return pointer to the value of the node -*/ -void* SkipList::searchElement(int key) { - Node *x = header; - std::cout << "Searching for " + key << endl; - - for(int i = level; i >= 0; i--) { - while(x->forward[i] && x->forward[i]->key < key) x = x->forward[i]; - } - - x = x->forward[0]; - if(x && x->key == key){ - std::cout << "Found" << endl; - return x->value; - } else { - std::cout << "Not Found" << endl; - return nullptr; - } -} - -/* - * Display skip list level - */ -void SkipList::displayList() { - std::cout << "Displaying list:\n" << endl; - for(int i=0; i <= level; i++) { - Node *node = header->forward[i]; - std::cout << "Level " << (i) << ": "; - while(node != nullptr) { - std::cout << node->key << " "; - node = node->forward[i]; - } - std::cout << endl; - } -} - +} // namespace data_structure /** * Main function: * Creates and inserts random 2^[number of levels] * elements into the skip lists and than displays it - */ -int main() -{ + */ +int main() { std::srand(std::time(nullptr)); - SkipList lst; + data_structure::SkipList lst; - for (int j = 0; j < (1 << (MAX_LEVEL+1)); j++){ - int k = (std::rand()%( 1 << (MAX_LEVEL+2)) + 1); - lst.insertElement(k, &j); + for (int j = 0; j < (1 << (data_structure::MAX_LEVEL + 1)); j++) { + int k = (std::rand() % (1 << (data_structure::MAX_LEVEL + 2)) + 1); + lst.insertElement(k, &j); } lst.displayList(); - -} +} From c15c962f02d284f50b7a62b4af92fe2ef696a7a1 Mon Sep 17 00:00:00 2001 From: Krishna Vedala <7001608+kvedala@users.noreply.github.com> Date: Sun, 12 Jul 2020 17:04:09 -0400 Subject: [PATCH 35/38] since we are using smart pointers, an explicit destructor is not required --- data_structures/skip_list.cpp | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/data_structures/skip_list.cpp b/data_structures/skip_list.cpp index d7982f866..2cb78b8c8 100644 --- a/data_structures/skip_list.cpp +++ b/data_structures/skip_list.cpp @@ -67,22 +67,6 @@ class SkipList { header = std::shared_ptr(new Node(-1, MAX_LEVEL)); } - /** - * Destructor for skiplist class - */ - ~SkipList() { - for (int i = 0; i <= level; i++) { - std::shared_ptr node = header->forward[i]; - std::shared_ptr temp; - while (node != nullptr) { - temp = node; - node = node->forward[i]; - temp.reset(); - } - } - header.reset(); - } - /** * Returns random level of the skip list. * Every higher level is 2 times less likely. From 47f5ad9aaf0f497afec0bdcbb0138c344b9364e8 Mon Sep 17 00:00:00 2001 From: Krishna Vedala <7001608+kvedala@users.noreply.github.com> Date: Sun, 12 Jul 2020 17:47:57 -0400 Subject: [PATCH 36/38] fix randomlevel float conversion --- data_structures/skip_list.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/data_structures/skip_list.cpp b/data_structures/skip_list.cpp index 2cb78b8c8..b1b24ea20 100644 --- a/data_structures/skip_list.cpp +++ b/data_structures/skip_list.cpp @@ -41,7 +41,7 @@ struct Node { * @param key is number that is used for comparision * @param level is the maximum level node's going to added */ - Node(int key, int level, void* value = nullptr) : key(key) { + Node(int key, int level, void* value = nullptr) : key(key), value(value) { // Initialization of forward vector for (int i = 0; i < (level + 1); i++) { forward.push_back(nullptr); @@ -74,7 +74,7 @@ class SkipList { */ int randomLevel() { int lvl = 0; - while (static_cast(std::rand() / RAND_MAX) < PROBABILITY && + while (static_cast(std::rand()) / RAND_MAX < PROBABILITY && lvl < MAX_LEVEL) lvl++; return lvl; @@ -185,7 +185,7 @@ class SkipList { * Display skip list level */ void displayList() { - std::cout << "Displaying list:\n" << std::endl; + std::cout << "Displaying list:\n"; for (int i = 0; i <= level; i++) { std::shared_ptr node = header->forward[i]; std::cout << "Level " << (i) << ": "; From dc4a72c4181ee000cfdfede684c089adbc3a0774 Mon Sep 17 00:00:00 2001 From: Krishna Vedala <7001608+kvedala@users.noreply.github.com> Date: Mon, 13 Jul 2020 08:07:10 -0400 Subject: [PATCH 37/38] fix doc comment block --- data_structures/skip_list.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data_structures/skip_list.cpp b/data_structures/skip_list.cpp index b1b24ea20..39dda5ce6 100644 --- a/data_structures/skip_list.cpp +++ b/data_structures/skip_list.cpp @@ -181,7 +181,7 @@ class SkipList { } } - /* + /** * Display skip list level */ void displayList() { From eefe46688deb4197d14a7d123135037c7888a304 Mon Sep 17 00:00:00 2001 From: Krishna Vedala <7001608+kvedala@users.noreply.github.com> Date: Mon, 13 Jul 2020 08:07:44 -0400 Subject: [PATCH 38/38] main function must return --- data_structures/skip_list.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/data_structures/skip_list.cpp b/data_structures/skip_list.cpp index 39dda5ce6..cc679a31c 100644 --- a/data_structures/skip_list.cpp +++ b/data_structures/skip_list.cpp @@ -216,4 +216,6 @@ int main() { } lst.displayList(); + + return 0; }