#tree #set #internal #allocation #integer #structure #veb

nightly flat-veb

Fast implementation of vEB trees without internal allocation

1 unstable release

0.1.2 Jul 31, 2022
0.1.1 Jul 31, 2022
0.1.0 Jul 30, 2022

#1040 in Data structures

Download history 2/week @ 2024-02-15 7/week @ 2024-02-22 3/week @ 2024-02-29 2/week @ 2024-03-07 29/week @ 2024-03-28 27/week @ 2024-04-04

56 downloads per month

MIT license

22KB
430 lines

flat-veb

Fast implementation of vEB trees without internal allocation.

van Emde Boas tree is a data structure for maintaining a set of integers of bounded size supporting the following queries:

  • insert(x) - inserts the integer x into the set
  • remove(x) - removes the integer x from the set
  • contains(x) - returns whether the set contains x
  • next(x) - returns the smallest integer in the set that is greater or equal to x
  • prev(x) - returns the smallest integer in the set that is greater or equal to x

All of these use $\mathcal{O}(\log \log U)$ time, and the structure uses $\mathcal{O}(U)$ space, where $U$ is the biggest integer you can put in the set.

Usage

use the trait VEBTree and the type VEBTreeX where X is the number of bits in the elements you will insert. In other words, with VEBTreeX you can only insert elements with value less than 1 << X.

use flat_veb::{VEBTree, VEBTree24};
let mut tree = VEBTree24::new();

// note that VEBTree24 is a quite big object, using over 2 MB while empty,
// but the size doesn't increase when elements are inserted.

assert_eq!(tree.insert(123), true); // returns true if it wasn't already there
assert_eq!(tree.insert(1337), true);
assert_eq!(tree.insert(123), false); // false because it was already there

assert_eq!(tree.contains(123), true);
assert_eq!(tree.contains(42), false);

assert_eq!(tree.next(42), Some(123));
assert_eq!(tree.next(123), Some(123));
assert_eq!(tree.next(124), Some(1337));

assert_eq!(tree.remove(1337), true);
assert_eq!(tree.remove(1337), false); // it's not there when removing it the second time

assert_eq!(tree.next(124), None); // there is no element in te set >= 124

Performance

It is natural to use internal heap allocation and indirection to implement recursive data structures like vEB tree, but this implementation avoid that to be faster, at the cost of a bit cumbersome API.

A BTreeSet can do all of the operations a vEB tree can and much more, but is slower. A vEB tree is more appropriate if there are enough operations that the speed improvement matters, but the integers are small enough that the vEB tree doesn't take too much space.

vEB tree is about 10 times faster than BTreeSet on tests downloaded from https://judge.yosupo.jp/problem/predecessor_problem, but this includes IO, which is probably a significant amount of the time spent for the vEB tree. Better benchmarks are needed.

Todo

  • better benchmarks
  • create a function to return a Box of appropriate capacity
  • reverse iterator

License: MIT

No runtime deps