Open
Graph Drawing
Framework

 v. 2023.09 (Elderberry)
 

Skiplist.h
Go to the documentation of this file.
1 
32 #pragma once
33 
34 #include <ogdf/basic/memory.h>
35 
36 #include <cstdlib>
37 #include <ctime>
38 
39 namespace ogdf {
40 
41 template<class X>
43 
45 
53 template<class X>
54 class 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 
76 public:
78  Skiplist() : m_lSize(0) {
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 
163 private:
164  int m_lSize;
166  int m_height;
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 
196 template<class X>
197 class SkiplistIterator {
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 
204 public:
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 }
ogdf
The namespace for all OGDF objects.
Definition: multilevelmixer.cpp:39
ogdf::Skiplist::Element::Element
Element(const X &item, int height)
Definition: Skiplist.h:67
ogdf::Skiplist::m_lSize
int m_lSize
Definition: Skiplist.h:164
ogdf::Skiplist::add
void add(X item)
Adds the item item into the skiplist [O'(log n)].
Definition: Skiplist.h:105
ogdf::Skiplist::empty
bool empty() const
Returns true if the skiplist contains no elements.
Definition: Skiplist.h:135
ogdf::Skiplist::isElement
bool isElement(X item) const
Returns true if the item item is contained in the skiplist [O'(log n)].
Definition: Skiplist.h:92
ogdf::SkiplistIterator::SkiplistIterator
SkiplistIterator(const typename Skiplist< X >::Element *e)
Definition: Skiplist.h:202
ogdf::SkiplistIterator::operator++
SkiplistIterator< X > & operator++()
Move the iterator one item forward (prefix notation)
Definition: Skiplist.h:211
ogdf::Skiplist::Element::next
Element ** next
Definition: Skiplist.h:64
ogdf::Skiplist::m_start
Element ** m_start
Definition: Skiplist.h:165
OGDF_NEW_DELETE
#define OGDF_NEW_DELETE
Makes the class use OGDF's memory allocator.
Definition: memory.h:85
ogdf::Skiplist::Element
friend class Element
Definition: Skiplist.h:56
ogdf::Skiplist::clear
void clear(bool killData=false)
Clears the current skiplist.
Definition: Skiplist.h:142
ogdf::Skiplist::Element::~Element
~Element()
Definition: Skiplist.h:71
ogdf::SkiplistIterator::operator*
const X & operator*() const
Returns the item to which the iterator points.
Definition: Skiplist.h:206
ogdf::SkiplistIterator::valid
bool valid() const
Definition: Skiplist.h:208
ogdf::Skiplist::Element::entry
X entry
Definition: Skiplist.h:63
ogdf::Skiplist
A randomized skiplist.
Definition: Skiplist.h:54
ogdf::Skiplist::random_height
int random_height()
Definition: Skiplist.h:169
ogdf::Skiplist::m_height
int m_height
Definition: Skiplist.h:166
ogdf::Skiplist::end
const SkiplistIterator< X > end() const
returns an invalid iterator
Definition: Skiplist.h:161
ogdf::Skiplist::Skiplist
Skiplist()
Construct an initially empty skiplist.
Definition: Skiplist.h:78
ogdf::Skiplist::begin
const SkiplistIterator< X > begin() const
returns an (forward) iterator for the skiplist
Definition: Skiplist.h:158
ogdf::Skiplist::~Skiplist
~Skiplist()
Definition: Skiplist.h:86
ogdf::SkiplistIterator::operator++
SkiplistIterator< X > operator++(int)
Move the iterator one item forward (prefix notation)
Definition: Skiplist.h:217
ogdf::SkiplistIterator::operator!=
bool operator!=(const SkiplistIterator< X > other) const
Definition: Skiplist.h:225
ogdf::Skiplist::size
int size() const
Returns the current size of the skiplist, i.e., the number of elements.
Definition: Skiplist.h:132
ogdf::Skiplist::m_realheight
int m_realheight
Definition: Skiplist.h:167
ogdf::SkiplistIterator::operator==
bool operator==(const SkiplistIterator< X > other) const
Definition: Skiplist.h:223
ogdf::SkiplistIterator
Forward-Iterator for Skiplists.
Definition: Skiplist.h:42
memory.h
Declaration of memory manager for allocating small pieces of memory.
ogdf::Skiplist::grow
void grow(int newheight)
Definition: Skiplist.h:177
ogdf::SkiplistIterator::el
const Skiplist< X >::Element * el
Definition: Skiplist.h:200
ogdf::Skiplist::Element
Internal structure to hold the items and internal forward pointers of the skiplist.
Definition: Skiplist.h:59