Open
Graph Drawing
Framework

 v. 2023.09 (Elderberry)
 

Loading...
Searching...
No Matches
Skiplist.h
Go to the documentation of this file.
32#pragma once
33
34#include <ogdf/basic/memory.h>
35
36#include <cstdlib>
37#include <ctime>
38
39namespace ogdf {
40
41template<class X>
43
45
53template<class X>
54class Skiplist {
55 friend class SkiplistIterator<X>;
56 friend class Element;
57
59 class Element {
60 friend class Skiplist<X>;
61 friend class SkiplistIterator<X>;
62
63 X entry; // content
64 Element** next; // successor elements
65
66 // construction
67 Element(const X& item, int height) : entry(item) {
68 next = (Element**)malloc(height * sizeof(Element*));
69 }
70
71 ~Element() { free(next); }
72
74 };
75
76public:
79 srand((unsigned int)time(nullptr));
80 m_realheight = 5;
81 m_height = 1;
82 m_start = (Element**)malloc(m_realheight * sizeof(Element*));
83 m_start[0] = nullptr;
84 }
85
87 clear();
88 free(m_start);
89 }
90
92 bool isElement(X item) const {
93 int h = m_height - 1;
94 Element** cur = m_start; // wheeha!
95 while (true) {
96 if (cur[h] && *(cur[h]->entry) < *item) { //nxt != nullptr
97 cur = cur[h]->next;
98 } else if (--h < 0) {
99 return cur[0] && *(cur[0]->entry) == *item;
100 }
101 }
102 }
103
105 void add(X item) {
106 m_lSize++;
107
108 int nh = random_height();
109 Element* n = new Element(item, nh);
110 if (nh > m_height) {
111 grow(nh);
112 }
113
114 int h = m_height - 1;
115 Element** cur = m_start; // wheeha!
116 while (true) {
117 if (cur[h] && *(cur[h]->entry) < *item) { //nxt != nullptr
118 cur = cur[h]->next;
119 } else {
120 if (h < nh) { // add only if new element is high enough
121 n->next[h] = cur[h];
122 cur[h] = n;
123 }
124 if (--h < 0) {
125 return;
126 }
127 }
128 }
129 }
130
132 int size() const { return m_lSize; }
133
135 bool empty() const { return m_lSize == 0; }
136
138
142 void clear(bool killData = false) {
143 Element* item = m_start[0];
144 while (item) {
145 Element* old = item;
146 item = item->next[0];
147 if (killData) {
148 delete old->entry;
149 }
150 delete old;
151 }
152 m_lSize = 0;
153 m_height = 1;
154 m_start[0] = nullptr;
155 }
156
158 const SkiplistIterator<X> begin() const { return m_start[0]; }
159
161 const SkiplistIterator<X> end() const { return nullptr; }
162
163private:
168
170 int h = 1;
171 while (rand() > RAND_MAX / 2) {
172 h++;
173 }
174 return h;
175 }
176
177 void grow(int newheight) {
178 if (newheight > m_realheight) {
179 m_realheight = newheight;
180 Element** newStart =
181 static_cast<Element**>(realloc(m_start, m_realheight * sizeof(Element*)));
182 if (newStart == nullptr) {
183 free(m_start);
184 } else {
185 m_start = newStart;
186 }
187 }
188 for (int i = newheight; i-- > m_height;) {
189 m_start[i] = nullptr;
190 }
191 m_height = newheight;
192 }
193};
194
196template<class X>
198 friend class Skiplist<X>;
199
200 const typename Skiplist<X>::Element* el;
201
202 SkiplistIterator(const typename Skiplist<X>::Element* e) { el = e; }
203
204public:
206 const X& operator*() const { return el->entry; }
207
208 bool valid() const { return el != nullptr; }
209
212 el = el->next[0];
213 return *this;
214 }
215
218 SkiplistIterator<X> it = *this;
219 el = el->next[0];
220 return it;
221 }
222
223 bool operator==(const SkiplistIterator<X> other) const { return el == other.el; }
224
225 bool operator!=(const SkiplistIterator<X> other) const { return !operator==(other); }
226};
227
228}
Internal structure to hold the items and internal forward pointers of the skiplist.
Definition Skiplist.h:59
Element(const X &item, int height)
Definition Skiplist.h:67
A randomized skiplist.
Definition Skiplist.h:54
void grow(int newheight)
Definition Skiplist.h:177
const SkiplistIterator< X > begin() const
returns an (forward) iterator for the skiplist
Definition Skiplist.h:158
const SkiplistIterator< X > end() const
returns an invalid iterator
Definition Skiplist.h:161
void clear(bool killData=false)
Clears the current skiplist.
Definition Skiplist.h:142
bool isElement(X item) const
Returns true if the item item is contained in the skiplist [O'(log n)].
Definition Skiplist.h:92
bool empty() const
Returns true if the skiplist contains no elements.
Definition Skiplist.h:135
Element ** m_start
Definition Skiplist.h:165
void add(X item)
Adds the item item into the skiplist [O'(log n)].
Definition Skiplist.h:105
int random_height()
Definition Skiplist.h:169
Skiplist()
Construct an initially empty skiplist.
Definition Skiplist.h:78
int size() const
Returns the current size of the skiplist, i.e., the number of elements.
Definition Skiplist.h:132
Forward-Iterator for Skiplists.
Definition Skiplist.h:197
SkiplistIterator(const typename Skiplist< X >::Element *e)
Definition Skiplist.h:202
bool operator!=(const SkiplistIterator< X > other) const
Definition Skiplist.h:225
const X & operator*() const
Returns the item to which the iterator points.
Definition Skiplist.h:206
bool valid() const
Definition Skiplist.h:208
bool operator==(const SkiplistIterator< X > other) const
Definition Skiplist.h:223
SkiplistIterator< X > operator++(int)
Move the iterator one item forward (prefix notation)
Definition Skiplist.h:217
const Skiplist< X >::Element * el
Definition Skiplist.h:200
SkiplistIterator< X > & operator++()
Move the iterator one item forward (prefix notation)
Definition Skiplist.h:211
#define OGDF_NEW_DELETE
Makes the class use OGDF's memory allocator.
Definition memory.h:85
Declaration of memory manager for allocating small pieces of memory.
The namespace for all OGDF objects.