4#ifdef LINKED_LIST_VISUALIZATION_H
5#include "../../visualization/list_visual/linked_list_visualization.h"
13#include <unordered_set>
29 inline explicit skip_list(
int MAX_LEVEL,
float PROB) {
32 MAX_LEVEL = MAX_LEVEL;
33 root = std::make_shared<node>(0, MAX_LEVEL);
35 throw std::invalid_argument(
"Max level value is too high");
37 if (PROB > 0.0 && PROB < 1.0) {
39 }
else if (PROB >= 1.0) {
40 throw std::invalid_argument(
"Probability value is greater or equal to 1");
41 }
else if (PROB <= 0.0) {
42 throw std::invalid_argument(
"Probability value is smaller or equal to 0");
44 }
catch (std::invalid_argument& e) {
45 std::cerr << e.what() <<
'\n';
56 : level(s.level), PROB(s.PROB), MAX_LEVEL(s.MAX_LEVEL), root(s.root) {}
66 MAX_LEVEL = s.MAX_LEVEL;
81 std::shared_ptr<node> head = root;
82 std::vector<std::shared_ptr<node>> update(MAX_LEVEL + 1,
nullptr);
84 for (
int i = level; i >= 0; i--) {
85 while (head->next[i] !=
nullptr && head->next[i]->key < key) {
92 if (!head || head->key != key) {
95 for (
int i = level + 1; i < lvl + 1; i++) {
101 std::shared_ptr<node> nn = std::make_shared<node>(key, lvl);
102 for (
int i = 0; i <= lvl; i++) {
103 nn->next[i] = update[i]->next[i];
104 update[i]->next[i] = nn;
130 std::shared_ptr<node> x = root;
131 std::vector<std::shared_ptr<node>> update(MAX_LEVEL + 1,
nullptr);
133 for (int64_t i = level; i >= 0; i--) {
134 while (x->next[i] && x->next[i]->key < key) {
141 if (x && x->key == key) {
142 for (int64_t i = 0; i <= level; i++) {
143 if (update[i]->next[i] != x) {
146 update[i]->next[i] = x->next[i];
148 while (level > 0 && root->next[level] ==
nullptr) {
160 std::shared_ptr<node> x = root;
161 for (int64_t i = level; i >= 0; i--) {
162 while (x->next[i] && x->next[i]->key < key) {
167 if (x && x->key == key) {
178#ifdef ENABLE_LIST_VISUALIZATION
179 inline void visualize() {
180 std::string generated = this->generate();
181 linked_list_visualization::visualize(generated);
189 std::shared_ptr<node> root = l.root;
191 for (
int i = 0; i <= l.level; i++) {
193 std::shared_ptr<node> curr = l.root->next[i];
194 while (curr !=
nullptr) {
195 out << curr->key <<
" ";
196 curr = curr->next[i];
215 std::vector<std::shared_ptr<node>> next;
216 node(T key,
int level,
void* value =
nullptr) : key(key) {
217 for (
int i = 0; i < level + 1; i++) {
218 next.push_back(
nullptr);
224 float r = (float)rand() / RAND_MAX;
226 while (r < PROB && lvl < MAX_LEVEL) {
228 r = (float)rand() / RAND_MAX;
234 std::shared_ptr<node> root;
236 std::string generate_node(std::string node_val,
int levs) {
239 gen +=
" [label=\"<";
240 gen += std::to_string(levs);
243 for (
int i = levs - 1; i >= 0; i--) {
245 gen += std::to_string(i);
254 std::string generate_edge(std::string prev_val, std::string curr_val,
int lev) {
258 gen += std::to_string(lev);
262 gen += std::to_string(lev);
267 std::string generate() {
269 gen +=
"rankdir=LR;";
271 gen +=
"node [shape=record;]";
273 std::unordered_set<std::string> S;
274 int m_level = std::min(level, (
int)root->next.size());
275 gen += generate_node(
"root", m_level + 1);
276 gen += generate_node(
"NULL", m_level + 1);
277 gen += generate_edge(
"root",
"NULL", m_level + 1);
278 for (
int i = m_level; i >= 0; i--) {
279 std::shared_ptr<node> head = root;
280 head = head->next[i];
281 std::string prev_val =
"root";
282 std::string head_key;
284 if (std::is_same_v<T, std::string>) {
285 head_key = head->key;
287 head_key = to_string(head->key);
289 if (S.find(head_key) == S.end()) {
291 gen += generate_node(head_key, i);
293 gen += generate_edge(prev_val, head_key, i);
295 head = head->next[i];
297 gen += generate_edge(prev_val,
"NULL", i);
308 std::shared_ptr<node> ptr;
315 explicit Iterator(std::shared_ptr<node> ptr) noexcept : ptr(ptr) {}
334 if (ptr !=
nullptr) {
Iterator class.
Definition skip_list.h:306
Iterator operator++(int)
operator ++ for type Iterator
Definition skip_list.h:345
T operator*()
operator * for type Iterator
Definition skip_list.h:364
bool operator!=(const Iterator &it)
operator != for type Iterator
Definition skip_list.h:357
Iterator & operator=(std::shared_ptr< node > current)
= operator for Iterator type*
Definition skip_list.h:323
Iterator & operator++()
operator ++
Definition skip_list.h:333
Iterator(std::shared_ptr< node > ptr) noexcept
Construct a new Iterator object.
Definition skip_list.h:315
skip_list(int MAX_LEVEL, float PROB)
skip_list constructor.
Definition skip_list.h:29
Iterator end()
pointer that points to the last element of the list
Definition skip_list.h:123
void remove(T key)
remove function.
Definition skip_list.h:129
~skip_list() noexcept
Destroy the skip list object.
Definition skip_list.h:74
skip_list & operator=(const skip_list &s)
operator = for the skip_list class
Definition skip_list.h:63
skip_list(const skip_list &s)
Copy constructor for the skip_list class.
Definition skip_list.h:55
friend std::ostream & operator<<(std::ostream &out, skip_list< T > &l)
visualize function returns a .dot file that can be previewd with graphviz plugin in vscode
Definition skip_list.h:188
Iterator begin()
pointer that points to the first element of the list
Definition skip_list.h:116
void insert(T key)
insert function.
Definition skip_list.h:80
bool search(T key)
search function.
Definition skip_list.h:159