Problem
Let such that . We want to design a data structure , that maintains elements from the finite domain , with the following properties:
It supports insert, successor operations in time.
Base Case
If , then the tree consists of a bit array of size two. Insertion and deletion involves setting the corresponding bit to and , respectively. Finding successor of an element involving scanning the array. All operations has time complexity .
General Cases
Naive Array
We could maintain a bit array of size . Insertion and deletion can still be performed in time. However, successor has time complexity .
Naive Recursion
We can partition the bit array into clusters, denoted .cluster, , .cluster.
Each cluster consists of consecutive elements, and maintains a summary bit for deciding whether it is empty.
The summary bits are grouped into an array .summary.
Now insertion time is still . Deletion and successor can be performed in time.

van Emde Boas Tree
van Emde Boas Tree (vEB Tree) is an advanced data structure based on the divide-and-conquer strategy.
Definition
Denote the structure over domain as . It is defined recursively as follows:
Definition :
- If , then is just a simple bit array of size .
- Otherwise, has the following components:
- Two elements, max and min, each of size bits.
- Children trees, , each of type .
- Summary tree, , of type .
Hence, if , then contains subtrees.
Let be an instance of . If an element is stored in , we write . The components of have the following functionalities.
- .max and .min maintain the maximum and minimum elements in the tree. These two elements will not be stored in the children trees or the summary tree.
- For each , the child tree stores elements for which 1) ; 2) .
- The summary tree stores the for which is not empty.
Operations
We need the following subroutine.
Procedure exchange:
If then
swap;
Elif then
swap;
Next we consider inserting an element into and structure .
If is empty, then the algorithm sets and to .
If consists of one element (in this case, ), then is stored in either or .
Otherwise, is swapped with , if , or is swapped with , if . Then the algorithm extracts the first and the last bits, denoted as and respectively, from the binary representation of . The value of will be inserted into the child tree . If is empty, the algorithm needs to insert into the summary tree , indicating that is not empty after inserting into it.
Procedure insert:
If is empty then
; ;
If contains only one element then
exchange;
else
exchange;
If is empty then
insert;
insert;
To find the successor of from , the algorithm first checks whether . If so, it returns null.
Otherwise, it inspects the child tree . If it is non-empty, and is smaller than the largest element in , the algorithm returns the successor of in .
If not, the algorithm try to find the smallest such that the child tree is non-empty subtree. If such exists, the algorithm returns the smallest element from . Otherwise, is returned.
Procedure successor:
If then
return null;
;
If is empty or then
successor;
If null then
return ;
Else
return
else
return successor.
Time Analysis
Theorem. Inserting an element into an instance has time complexity .
Proof. The claim holds trivially if contains zero or one element. Otherwise, let be the time complexity for inserting into . We show that
Solving the recursion gives .
If is non-empty, the only one recursion, i.e., insert, is executed. Therefore, holds.
If is empty, two recursions, i.e., insert, insert, are executed. However, in this case, the second recursion has time complexity . Hence, still holds.
Theorem. Finding the successor of an element from an instance has time complexity .
Proof. The successor operation of invokes at most one recursive call, therefore its running time satisfies , which solves to .
Space Analysis
Theorem. can be implemented with space.
Proof. Denote the space usage of as . Then we have . For , a structure stores
- Elements and , which takes words.
- Pointers to subtrees, which takes words.
- subtrees, each taking space .
Therefore, the total space usage is given by
To solve the recursion, assume that (by proper scaling). Further, assuming that . Then, we can verity that the recursion holds:
Theorem. can be implemented with space.
Proof. One improvement to the previous approach is to avoid maintaining all pointers to the children trees , and constructing all of them explicitly.
Instead, we construct a child tree only if it is non-empty, and keep a hash table in the structure, which stores the pointers to these non-empty children trees.
Inserting an element has time complexity , therefore it can creates at most pointers, as well as subtrees. Since when a subtree is created, it takes space , therefore the total space usage is .
This bound is tight. Suppose we want to insert an element into a structure. If is empty, then we invoke the recursion insert to insert into the summary. However, in this case, we need to crete the subtree for (which takes space), insert the pointer for into the hash table (which also takes space). This can happen for each recursion, therefore the total space overhead is for a single insertion.
Reference
[1] T. H. Cormen, Ed., Introduction to algorithms 3rd, 3rd ed. Cambridge, Mass: MIT Press, 2009.