200#include <tclap/CmdLine.h>
203using namespace Aleph;
213 cout <<
"\n=== Basic Skip List Operations ===" <<
endl;
219 cout <<
"\nInserting elements..." <<
endl;
220 vector<int> data = {42, 17, 99, 23, 8, 64, 31, 55, 100, 5};
225 cout <<
" Inserted: " << val <<
endl;
228 cout <<
"\nSkip list size: " << skiplist.
size() <<
endl;
231 cout <<
"\n--- Search Operations ---" <<
endl;
237 cout <<
" search(" << key <<
"): ";
245 cout <<
"\nUsing has() method:" <<
endl;
246 cout <<
" has(42): " << (skiplist.
has(42) ?
"yes" :
"no") <<
endl;
247 cout <<
" has(50): " << (skiplist.
has(50) ?
"yes" :
"no") <<
endl;
250 cout <<
"\n--- Sorted Traversal ---" <<
endl;
251 cout <<
"Elements in ascending order:" <<
endl;
255 cout << it.get_curr() <<
" ";
259 cout <<
"\n--- Removal Operations ---" <<
endl;
265 cout <<
"Trying to remove non-existent 1000..." <<
endl;
270 cout <<
"Final elements: ";
272 cout << it.get_curr() <<
" ";
281 cout <<
"\n=== Skip List with Strings ===" <<
endl;
287 "algorithm",
"binary",
"complexity",
"data",
"efficient",
288 "function",
"graph",
"hash",
"index",
"join"
291 cout <<
"Building vocabulary..." <<
endl;
296 cout <<
"\nWords in alphabetical order:" <<
endl;
298 cout <<
" " << it.get_curr() <<
endl;
302 cout <<
" 'complexity' exists: " << (words.
has(
"complexity") ?
"yes" :
"no") <<
endl;
303 cout <<
" 'hello' exists: " << (words.
has(
"hello") ?
"yes" :
"no") <<
endl;
311 cout <<
"\n=== Functional Programming with Skip Lists ===" <<
endl;
314 for (
int i = 1; i <= 20; i++)
317 cout <<
"Numbers (multiples of 3 up to 60):" <<
endl;
324 cout <<
" all > 0: " << (
numbers.
all([](
int n) {
return n > 0; }) ?
"true" :
"false") <<
endl;
325 cout <<
" exists 30: " << (
numbers.
exists([](
int n) {
return n == 30; }) ?
"true" :
"false") <<
endl;
326 cout <<
" exists 31: " << (
numbers.
exists([](
int n) {
return n == 31; }) ?
"true" :
"false") <<
endl;
331 cout <<
"Expected sum (3+6+...+60): " << (3 * 20 * 21 / 2) <<
endl;
339 cout <<
"\n=== Performance Benchmark ===" <<
endl;
340 cout <<
"Comparing DynSkipList vs std::set with " << n <<
" elements" <<
endl;
347 for (
size_t i = 0; i < n; i++)
358 auto start = chrono::high_resolution_clock::now();
361 auto end = chrono::high_resolution_clock::now();
362 double skiplist_insert = chrono::duration<double, milli>(end - start).count();
364 start = chrono::high_resolution_clock::now();
368 end = chrono::high_resolution_clock::now();
369 double skiplist_search = chrono::duration<double, milli>(end - start).count();
374 start = chrono::high_resolution_clock::now();
377 end = chrono::high_resolution_clock::now();
378 double stdset_insert = chrono::duration<double, milli>(end - start).count();
380 start = chrono::high_resolution_clock::now();
384 end = chrono::high_resolution_clock::now();
385 double stdset_search = chrono::duration<double, milli>(end - start).count();
388 cout <<
"\n" <<
setw(15) <<
"Operation"
389 <<
setw(18) <<
"DynSkipList (ms)"
390 <<
setw(18) <<
"std::set (ms)"
408 cout <<
"DynSkipList size: " << skiplist.
size() <<
" (unique elements)" <<
endl;
412 cout <<
"\nNote: Skip Lists trade some raw performance for:" <<
endl;
413 cout <<
" - Simpler implementation (no rotations)" <<
endl;
414 cout <<
" - Easier concurrent access" <<
endl;
415 cout <<
" - Ordered iteration for range scans" <<
endl;
423 cout <<
"\n=== Skip List Structure Visualization ===" <<
endl;
424 cout <<
"\nConceptual view of a skip list with keys 3, 6, 7, 9, 12, 17, 19, 21:" <<
endl;
426 cout <<
" Level 3: HEAD ---------------------------------> 12 ---------------------------------> NIL" <<
endl;
427 cout <<
" Level 2: HEAD ----------------> 6 ------------> 12 ----------------> 19 ------------> NIL" <<
endl;
428 cout <<
" Level 1: HEAD --------> 3 ----> 6 ----> 9 ----> 12 ----> 17 -------> 19 ----> 21 ----> NIL" <<
endl;
429 cout <<
" Level 0: HEAD -> 3 -> 6 -> 7 -> 9 -> 12 -> 17 -> 19 -> 21 -> NIL" <<
endl;
433 cout <<
" 1. Start at HEAD, Level 3" <<
endl;
434 cout <<
" 2. 12 < 17, move right to 12" <<
endl;
435 cout <<
" 3. 12 -> NIL, drop to Level 2" <<
endl;
436 cout <<
" 4. 19 > 17, drop to Level 1" <<
endl;
437 cout <<
" 5. 17 = 17, FOUND!" <<
endl;
438 cout <<
"\nSteps: ~4 (vs 6 for linear search)" <<
endl;
440 cout <<
"\nKey insight: Higher levels act as 'express lanes'" <<
endl;
441 cout <<
"Expected levels per node: log(n) with p=0.5" <<
endl;
448 TCLAP::CmdLine
cmd(
"Skip List Example",
' ',
"1.0");
450 TCLAP::SwitchArg
basicArg(
"b",
"basic",
451 "Show basic operations demo",
false);
452 TCLAP::SwitchArg
stringArg(
"s",
"string",
453 "Show string set demo",
false);
454 TCLAP::SwitchArg
funcArg(
"f",
"functional",
455 "Show functional programming demo",
false);
456 TCLAP::SwitchArg
benchArg(
"p",
"benchmark",
457 "Run performance benchmark",
false);
458 TCLAP::SwitchArg
visArg(
"i",
"visualize",
459 "Visualize skip list structure",
false);
460 TCLAP::ValueArg<size_t>
sizeArg(
"n",
"size",
461 "Number of elements for benchmark",
false, 100000,
"size_t");
462 TCLAP::ValueArg<unsigned>
seedArg(
"r",
"seed",
463 "Random seed",
false, 42,
"unsigned");
465 "Show detailed output",
false);
466 TCLAP::SwitchArg
allArg(
"a",
"all",
467 "Run all demos",
false);
488 unsigned seed =
seedArg.getValue();
495 cout <<
"=== Skip List: Probabilistic Data Structure ===" <<
endl;
496 cout <<
"Invented by William Pugh (1990)" <<
endl;
513 cout <<
"\n=== Complexity Summary ===" <<
endl;
514 cout <<
"Search: O(log n) expected" <<
endl;
515 cout <<
"Insert: O(log n) expected" <<
endl;
516 cout <<
"Delete: O(log n) expected" <<
endl;
517 cout <<
"Space: O(n) expected" <<
endl;
521 catch (TCLAP::ArgException& e)
523 cerr <<
"Error: " << e.error() <<
" for arg " << e.argId() <<
endl;
T & insert(const T &item)
Insert a new item by copy.
bool has_curr() const noexcept
Dynamic ordered set implemented with a Skip List.
size_t remove(const Key &key)
Remove a key from the set.
Iterator get_it() const noexcept
Alias for begin() - for generic programming.
Key * insert(const Key &key)
Insert an element into the set.
size_t size() const noexcept
Return the number of elements in the set.
bool has(const Key &key) const noexcept
Return true if the key exists in the set.
Key * search(const Key &key) const noexcept
Search for a key in the set.
size_t size() const noexcept
Count the number of elements of the list.
bool exists(Operation &op) const
Test for existence in the container of an element satisfying a criteria.
bool all(Operation &operation) const
Check if all the elements of container satisfy a condition.
void for_each(Operation &operation)
Traverse all the container and performs an operation on each element.
iterator end() noexcept
Return an STL-compatible end iterator.
Main namespace for Aleph-w library functions.
size_t size(Node *root) noexcept
bool verbose
Flag enabling verbose output.
DynList< T > maps(const C &c, Op op)
Classic map operation.
T sum(const Container &container, const T &init=T{})
Compute sum of all elements.
void visualize_structure()
Visualize skip list structure (small example)
void demonstrate_string_set()
Demonstrate skip list with strings.
void demonstrate_basic_operations()
Demonstrate basic Skip List operations.
void demonstrate_functional()
Demonstrate functional programming features.
void benchmark_comparison(size_t n, unsigned seed, bool verbose)
Benchmark skip list vs std::set.
Dynamic ordered set implemented with a Skip List.