Skip to content

GH-147: Skiplist in C++ #148

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 17 commits into from
Feb 8, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
update
  • Loading branch information
rain1024 committed Feb 8, 2023
commit ac6401cde8a3509d5e26cf5b2ccec4a6fb379b41
15 changes: 15 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,21 @@ A data structure is a data organization, management, and storage format that is
</tbody>
</table>

**Advanced Data Structures and Algorithms**

<table>
<thead>
<th>Advanced Concept</th>
<th>Programming Languages</th>
</thead>
<tbody>
<tr>
<td>Skiplist</td>
<td>
</td>
</tr>
</tbody>
</table>
## 🔆 Collections

**Competitive Programming Events**
Expand Down
3 changes: 3 additions & 0 deletions problems/skiplist/src/BUILD
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
load("@rules_cc//cc:defs.bzl", "cc_binary")

cc_binary(
name = "skiplist",
srcs = ["skiplist.cpp", "skiplist.h"],
copts = ["-std=c++17", "-Wall", "-Wextra", "-Werror"],
deps = [],
)
48 changes: 13 additions & 35 deletions problems/skiplist/src/skiplist.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,50 +3,28 @@

using namespace std;

// add class Class
class Class {
public:
int id;
string name;
Class(int id, string name) {
this->id = id;
this->name = name;
}
};

class Student {
public:
int id;
string name;
Class* classes[10];

Student(int id, string name) {
this->id = id;
this->name = name;
}

void addClass(Class* c) {

for (int i = 0; i < 10; i++) {
if (classes[i] == NULL) {
classes[i] = c;
break;
}
}
}
};

int main(){
cout << "Skiplist Program" << endl;

// create an skiplist
Skiplist sl;
// // insert 3 elements

cout << "\nInsert elements into Skiplist" << endl;
sl.insert(4);
sl.insert(2);
sl.insert(3);
sl.insert(8);
sl.insert(9);
sl.insert(1);
sl.show();

cout << "\nSearch elements" << endl;
cout << "- Search for 3: " << sl.search(3) << endl;
cout << "- Search for 5: " << sl.search(5) << endl;

cout << "\nRemove elements" << endl;
sl.remove(3);
sl.remove(5);
sl.show();

return 0;
}
133 changes: 71 additions & 62 deletions problems/skiplist/src/skiplist.h
Original file line number Diff line number Diff line change
@@ -1,114 +1,123 @@
#include <iostream>
#include <climits>
#include <iostream>

using namespace std;

// create class Skiplist

// Node struct
struct Node {
int key;
int level;
Node** forwards;
// constructor
Node(int key, int level){
Node(int key, int level) {
this->key = key;
this->level = level;
forwards = new Node*[level+1];
for(int i=0; i<=level; i++){
forwards = new Node*[level + 1];
for (int i = 0; i <= level; i++) {
forwards[i] = NULL;
}
}
};

class Skiplist {
public:
Skiplist();
~Skiplist();
void insert(int key);
void insert2(int key);
bool search(int key);
void erase(int key);
void show();
private:
Node* head;
int MAX_LEVEL;
public:
Skiplist(int max_level);
~Skiplist();
void insert(int key);
bool search(int key);
void remove(int key);
void show();

private:
Node* head;
int MAX_LEVEL;
};

Skiplist::Skiplist(){
MAX_LEVEL = 16;
Skiplist::Skiplist(int max_level = 4): MAX_LEVEL(max_level) {
head = new Node(INT_MIN, MAX_LEVEL);
srand(time(NULL));
}

Skiplist::~Skiplist(){
delete head;
}
Skiplist::~Skiplist() { delete head; }

void Skiplist::insert(int key){
// Create a new node with the given key.
// The level of the new node is a random number between 0 and MAX_LEVEL
// create random number between 0 to 1, if < 0.5, level++; otherwise, break
void Skiplist::insert(int key) {
int level = 0;

while(rand() % 2 && level < MAX_LEVEL){
while (rand() % 2 && level < MAX_LEVEL) {
level++;
}
Node* newNode = new Node(key, level);
// print newNode key and level
cout << "newNode (" << newNode->key << ", " << newNode->level << ")" << endl;

// Create a pointer to the current node

Node* current = head;
// Create an array of pointers to the previous nodes
// with size equal to the random level
Node** update = new Node*[level+1];
for(int i=0; i<=level; i++){
Node** update = new Node*[level + 1];
for (int i = 0; i <= level; i++) {
update[i] = NULL;
}

// // Traverse the list from the highest level to the lowest level
// // and find the previous node for each level
for(int i=level; i>=0; i--){
while(current->forwards[i] != NULL && current->forwards[i]->key < key){
// update the curent node
for (int i = level; i >= 0; i--) {
while (current->forwards[i] != NULL && current->forwards[i]->key < key) {
current = current->forwards[i];
}
// update the previous node for the current level
update[i] = current;
}

// cout << "Debug" << endl;

// // Set the next node for the new node to the next node of the previous node
// // for the lowest level
newNode->forwards[0] = update[0]->forwards[0];
// // Set the next node of the previous node for the lowest level to the new node
update[0]->forwards[0] = newNode;

for(int i=1; i<=level; i++){
for (int i = 0; i <= level; i++) {
newNode->forwards[i] = update[i]->forwards[i];
update[i]->forwards[i] = newNode;
}
}
}

bool Skiplist::search(int key) {
Node* current = head;
for (int i = MAX_LEVEL; i >= 0; i--) {
while (current->forwards[i] != NULL && current->forwards[i]->key < key) {
current = current->forwards[i];
}
}
if (current->forwards[0] != NULL && current->forwards[0]->key == key) {
return true;
}
return false;
}

// show skiplist of all levels
// level 0 will have all elements
// if an element is not exist in a level, print " "
void Skiplist::show(){
cout << "Skiplist::show" << endl;
void Skiplist::remove(int key) {
Node* current = head;
Node** update = new Node*[MAX_LEVEL + 1];
for (int i = 0; i <= MAX_LEVEL; i++) {
update[i] = NULL;
}

for (int i = MAX_LEVEL; i >= 0; i--) {
while (current->forwards[i] != NULL && current->forwards[i]->key < key) {
current = current->forwards[i];
}
update[i] = current;
}

current = current->forwards[0];

if (current && current->key == key) {
for (int i = 0; i <= MAX_LEVEL; i++) {
if (update[i]->forwards[i] != current) {
break;
}
update[i]->forwards[i] = current->forwards[i];
}
delete current;
}
delete[] update;
}

void Skiplist::show() {
Node* current = head;
while(current->forwards[0] != NULL){
while (current->forwards[0] != NULL) {
cout << current->forwards[0]->key << " ";
current = current->forwards[0];
}
cout << endl;

// show for each levels
for(int i=MAX_LEVEL; i>=0; i--){
for (int i = MAX_LEVEL; i >= 0; i--) {
cout << "Level " << i << ": ";
Node* current = head;
while(current->forwards[i] != NULL){
while (current->forwards[i] != NULL) {
cout << current->forwards[i]->key << " -> ";
current = current->forwards[i];
}
Expand Down