# Van Emde Boas Tree | Set 1 | Basics and Construction

It is highly recommended to fully understand Proto Van Emde Boas Tree. Van Emde Boas Tree supports search, successor, predecessor, insert and delete operations in O(lglgN) time which is faster than any of related data structures like priority queue, binary search tree, etc. Van Emde Boas Tree works with O(1) time-complexity for minimum and maximum query. Here N is the size of the universe over which tree is defined and lg is log base 2. Note: Van Emde Boas Data Structure’s key set must be defined over a range of 0 to n(n is positive integer of the form 2k) and it works when duplicate keys are not allowed. Abbreviations:

1. VEB is an abbreviation of Van Emde Boas tree.
2. VEB() is an abbreviation for VEB containing u number of keys.

Structure of Van Emde Boas Tree: Van Emde Boas Tree is a recursively defined structure.

1. u: Number of keys present in the VEB Tree.
2. Minimum: Contains the minimum key present in the VEB Tree.
3. Maximum: Contains the maximum key present in the VEB Tree.
4. Summary: Points to new VEB() Tree which contains overview of keys present in clusters array.
5. Clusters: An array of size each place in the array points to new VEB() Tree.

See the image below to understand the basics of Van Emde Boas Tree, although it does not represent the actual structure of Van Emde Boas Tree: Basic Understanding of Van Emde Boas Tree:

1. Van Emde Boas Tree is recursively defined structure similar to Proto Van Emde Boas Tree.
2. In Van Emde Boas Tree, Minimum and Maximum queries works in O(1) time as Van Emde Boas Tree stores Minimum and Maximum keys present in the tree structure.
3. Advantages of adding Maximum and Minimum attributes, which help to decrease time complexity:
• If any of Minimum and Maximum value of VEB Tree is empty(NIL or -1 in code) then there is no element present in the Tree.
• If both Minimum and Maximum is equal then only one value is present in the structure.
• If both are present and distinct then two or more elements are present in the Tree.
• We can insert and delete keys by just setting maximum and minimum values as per conditions in constant time( O(1) ) which helps in decreasing recursive call chain: If only one key is present in the VEB then to delete that key we simply set min and max to the nil value. Similarly, if no keys are present then we can insert by just setting min and max to the key we want to insert. These are O(1) operations.
• In successor and predecessor queries, we can take decisions from minimum and maximum values of VEB, which will make our work easier.

In Proto Van Emde Boas Tree the size of universe size is restricted to be of type 22k but in Van Emde Boas Tree, it allows the universe size to be exact power of two. So we need to modify High(x), low(x), generate_index() helper functions used in Proto Van Emde Boas Tree as below.

1. High(x): It will return floor( x/ceil() ), which is basically the cluster index in which the key x is present.
High(x) = floor(x/ceil())
1. Low(x): It will return x mod ceil( ) which is its position in the cluster.
Low(x) = x % ceil( )
1. generate_index(a, b) : It will return position of key from its position in cluster b and its cluster index a.
generate_index(a, b) = a * ceil() + b

Construction of Van Emde Boas Tree: Construction of Van Emde Boas Tree is very similar to Proto Van Emde Boas Tree. Difference here is that we are allowing the universe size to be any power of two, so that high(), low(), generate_index() will be different.

To construct, empty VEB: The procedure is the same as Proto VEB just two things minimum and maximum will be added in each VEB. To represent that minimum and maximum is null we will represent it as -1.

Note: In the base case, we just need minimum and maximum values because adding a cluster of size 2 will be redundant after the addition of min and max values.

Below is the implementation:

## C++

 // C++ implementation of the approach #include  using namespace std;   class Van_Emde_Boas {   public:     int universe_size;     int minimum;     int maximum;     Van_Emde_Boas* summary;     vector clusters;       // Function to return cluster numbers     // in which key is present     int high(int x)     {         int div = ceil(sqrt(universe_size));         return x / div;     }       // Function to return position of x in cluster     int low(int x)     {         int mod = ceil(sqrt(universe_size));         return x % mod;     }       // Function to return the index from     // cluster number and position     int generate_index(int x, int y)     {         int ru = ceil(sqrt(universe_size));         return x * ru + y;     }       // Constructor     Van_Emde_Boas(int size)     {         universe_size = size;         minimum = -1;         maximum = -1;           // Base case         if (size <= 2) {             summary = nullptr;             clusters = vector(0, nullptr);         }         else {             int no_clusters = ceil(sqrt(size));               // Assigning VEB(sqrt(u)) to summary             summary = new Van_Emde_Boas(no_clusters);               // Creating array of VEB Tree pointers of size sqrt(u)             clusters = vector(no_clusters, nullptr);               // Assigning VEB(sqrt(u)) to all of its clusters             for (int i = 0; i < no_clusters; i++) {                 clusters[i] = new Van_Emde_Boas(ceil(sqrt(size)));             }         }     } };   // Driver code int main() {     // New Van_Emde_Boas tree with u = 16     Van_Emde_Boas* akp = new Van_Emde_Boas(4); }

## Java

 class VanEmdeBoas {     int universeSize;     int minimum;     int maximum;     VanEmdeBoas summary;     VanEmdeBoas[] clusters;       public VanEmdeBoas(int size) {         this.universeSize = size;         this.minimum = -1;         this.maximum = -1;           if (size <= 2) {             this.summary = null;             this.clusters = new VanEmdeBoas[0];         } else {             int noClusters = (size + 1) / 2;               this.summary = new VanEmdeBoas(noClusters);             this.clusters = new VanEmdeBoas[noClusters];               for (int i = 0; i < noClusters; i++) {                 this.clusters[i] = new VanEmdeBoas((size + 1) / 2);             }         }     }       // Function to return cluster numbers     // in which key is present     int high(int x) {         int div = (this.universeSize + 1) / 2;         return x / div;     }       // Function to return position of x in cluster     int low(int x) {         int mod = (this.universeSize + 1) / 2;         return x % mod;     }       // Function to return the index from     // cluster number and position     int generateIndex(int x, int y) {         int ru = (this.universeSize + 1) / 2;         return x * ru + y;     }       public static void main(String[] args) {         // New VanEmdeBoas tree with u = 16         VanEmdeBoas akp = new VanEmdeBoas(16);     } }

## Python3

 # Python3 implementation of Van Emde Boas tree   class Van_Emde_Boas:     def __init__(self, size):         self.universe_size = size         self.minimum = -1         self.maximum = -1                   # Base case         if size <= 2:             self.summary = None             self.clusters = [None] * 0         else:             no_clusters = (size + 1) // 2                           # Assigning VEB(sqrt(u)) to summary             self.summary = Van_Emde_Boas(no_clusters)                           # Creating array of VEB Tree pointers of size sqrt(u)             self.clusters = [None] * no_clusters                           # Assigning VEB(sqrt(u)) to all of its clusters             for i in range(no_clusters):                 self.clusters[i] = Van_Emde_Boas((size + 1) // 2)       # Function to return cluster numbers     # in which key is present     def high(self, x):         div = (self.universe_size + 1) // 2         return x // div       # Function to return position of x in cluster     def low(self, x):         mod = (self.universe_size + 1) // 2         return x % mod       # Function to return the index from     # cluster number and position     def generate_index(self, x, y):         ru = (self.universe_size + 1) // 2         return x * ru + y   # Driver code if __name__ == '__main__':     # New Van_Emde_Boas tree with u = 16     akp = Van_Emde_Boas(16)

## Javascript

 class VanEmdeBoas {   constructor(size) {     this.universeSize = size;     this.minimum = -1;     this.maximum = -1;       // Base case     if (size <= 2) {       this.summary = null;       this.clusters = [];     } else {       const noClusters = Math.ceil(Math.sqrt(size));         // Assigning VanEmdeBoas(sqrt(u)) to summary       this.summary = new VanEmdeBoas(noClusters);         // Creating array of VanEmdeBoas pointers of size sqrt(u)       this.clusters = Array.from({ length: noClusters }, () => new VanEmdeBoas(Math.ceil(Math.sqrt(size))));         // Assigning VanEmdeBoas(sqrt(u)) to all of its clusters       for (let i = 0; i < noClusters; i++) {         this.clusters[i] = new VanEmdeBoas(Math.ceil(Math.sqrt(size)));       }     }   }     // Function to return cluster numbers in which key is present   high(x) {     const div = Math.ceil(Math.sqrt(this.universeSize));     return Math.floor(x / div);   }     // Function to return position of x in cluster   low(x) {     const mod = Math.ceil(Math.sqrt(this.universeSize));     return x % mod;   }     // Function to return the index from cluster number and position   generateIndex(x, y) {     const ru = Math.ceil(Math.sqrt(this.universeSize));     return x * ru + y;   } }   // Driver code const akp = new VanEmdeBoas(16); // New VanEmdeBoas tree with u = 16

Feeling lost in the world of random DSA topics, wasting time without progress? It's time for a change! Join our DSA course, where we'll guide you on an exciting journey to master DSA efficiently and on schedule.
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 geeks!

Previous
Next