0% found this document useful (0 votes)
42 views7 pages

Lecture 4: Divide and Conquer: Van Emde Boas Trees

The document describes van Emde Boas trees, which can perform insert, delete, and successor operations on a set of n elements in a range of size u in O(log log u) time. It achieves this through a series of improvements: splitting the range into clusters, recursively applying the data structure on clusters and a summary vector, and maintaining minimum and maximum elements to guide searches. The structure uses O(n) space through indirection and splitting/merging smaller structures.

Uploaded by

Cajun Sef
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
42 views7 pages

Lecture 4: Divide and Conquer: Van Emde Boas Trees

The document describes van Emde Boas trees, which can perform insert, delete, and successor operations on a set of n elements in a range of size u in O(log log u) time. It achieves this through a series of improvements: splitting the range into clusters, recursively applying the data structure on clusters and a summary vector, and maintaining minimum and maximum elements to guide searches. The structure uses O(n) space through indirection and splitting/merging smaller structures.

Uploaded by

Cajun Sef
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 7

Lecture 4 van Emde Boas 6.

046J Spring 2015

Lecture 4: Divide and Conquer:

van Emde Boas Trees

• Series of Improved Data Structures

• Insert, Successor

• Delete

• Space

This lecture is based on personal communication with Michael Bender, 2001.

Goal
We want to maintain n elements in the range {0, 1, 2, . . . , u − 1} and perform Insert,
Delete and Successor operations in O(log log u) time.
O(1)
• If n = nO(1) or n(log n) , then we have O(log log n) time operations

– Exponentially faster than Balanced Binary Search Trees


– Cooler queries than hashing

• Application: Network Routing Tables

– u = Range of IP Addresses → port to send (u = 232 in IPv4)

Where might the O(log log u) bound arise ?

• Binary search over O(log u) elements

• Recurrences
log u
– T (log u) = T 2 + O(1)

– T (u) = T ( u) + O(1)

Improvements
We will develop the van Emde Boas data structure by a series of improvements on
a very simple data structure.

Lecture 4 van Emde Boas 6.046J Spring 2015

Bit Vector
We maintain a vector V of size u such that V [ x ] = 1 if and only if x is in the set.
Now, inserts and deletes can be performed by just flipping the corresponding bit
in the vector. However, successor/predecessor requires us to traverse through the
vector to find the next 1-bit.

• Insert/Delete: O(1)

• Successor/Predecessor: O(u)

0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
0 1 0 0 0 0 0 0 0 1 1 0 0 0 0 1

Figure 1: Bit vector for u = 16. THe current set is {1, 9, 10, 15}.

Split Universe into Clusters



We can improve performance by splitting up the range {0, 1, 2, . . . , u − 1} into u
√ √
clusters of size u. If x = i u + j, then V [ x ] = V.Cluster [i ][ j].

low( x ) = x mod u = j
x
high( x ) = √ =i
u

index (i, j) = i u + j

0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
0 1 0 0 0 0 0 0 0 1 1 0 0 0 0 1

V.Cluster [0] V.Cluster [1] V.Cluster [2] V.Cluster [3]


Figure 2: Bit vector (u = 16) split into 16 = 4 clusters of size 4.

• Insert:

– Set V.cluster [ high( x )][low( x )] = 1 O(1)

Lecture 4 van Emde Boas 6.046J Spring 2015

– Mark cluster high( x ) as non-empty O(1)

• Successor:

– Look within cluster high( x ) O( u)

– Else, find next non-empty cluster i O( u)

– Find minimum entry j in that cluster O( u)

– Return index (i, j) Total = O( u)

Recurse

The three operations in Successor are also Successor calls to vectors of size u. We
can use recursion to speed things up.
√ √
• V.cluster [i ] is a size- u van Emde Boas structure (∀ 0 ≤ i < u)

• V.summary is a size- u van Emde Boas structure

• V.summary[i ] indicates whether V.cluster [i ] is nonempty

I NSERT (V, x )
1 Insert(V.cluster [ high( x )], low[ x ])
2 Insert(V.summary, high[ x ])

So, we get the recurrence:



T (u) = 2T ( u) + O(1)
log u
T ' (log u) = 2T ' + O(1)
2
=⇒ T (u) = T ' (log u) = O(log u)

S UCCESSOR (V, x )
1 i = high( x )
2 j = Successor (V.cluster [i ], j)
3 if j == ∞
4 i = Successor (V.summary, i )
5 j = Successor (V.cluster [i ], −∞)
6 return index (i, j)

Lecture 4 van Emde Boas 6.046J Spring 2015


T (u) = 3T ( u) + O(1)

 
' ' log u

T (log u) = 3T + O(1)
2
=⇒ T (u) = T ' (log u) = O((log u)log 3 ) ≈ O((log u)1.585 )

To obtain the O(log log u) running time, we need to reduce the number of re­
cursions to one.

Maintain Min and Max


We store the minimum and maximum entry in each structure. This gives an O(1)
time overhead for each Insert operation.

S UCCESSOR (V, x )

1 i = high( x )

2 if low( x ) < V.cluster [i ].max

3 j = Successor (V.cluster [i ], low( x ))

4 else i = Successor (V.summary, high( x ))

5 j = V.cluster [i ].min

6 return index (i, j)


T (u) = T ( u) + O(1)
=⇒ T (u) = O(log log u)

Don’t store Min recursively


The Successor call now needs to check for the min separately.

if x < V.min : return V.min (1)

Lecture 4 van Emde Boas 6.046J Spring 2015

I NSERT (V, x )
1 if V.min == None
2 V.min = V.max = x I O(1) time
3 return
4 if x < V.min
5 swap( x ↔ V.min)
6 if x > V.max
7 V.max = x)
8 if V.cluster [ high( x ) == None
9 Insert(V.summary, high( x )) I First Call
10 Insert(V.cluster [ high( x )], low( x )) I Second Call

If the first call is executed, the second call only takes O(1) time. So

T (u) = T ( u) + O(1)
=⇒ T (u) = O(log log u)

D ELETE (V, x )
1 if x == V.min I Find new min
2 i = V.summary.min
3 if i = None
4 V.min = V.max = None I O(1) time
5 return
6 V.min = index (i, V.cluster [i ].min) I Unstore new min
7 Delete(V.cluster [ high( x )], low( x )) I First Call
8 if V.cluster [ high( x )].min == None
9 Delete(V.summary, high( x )) I Second Call
10 I Now we update V.max
11 if x == V.max
12 if V.summary.max = None
13 else
14 i = V.summary.max
15 V.max = index (i, V.cluster [i ].max )

If the second call is executed, the first call only takes O(1) time. So

T (u) = T ( u) + O(1)
=⇒ T (u) = O(log log u)

Lecture 4 van Emde Boas 6.046J Spring 2015

Lower Bound [Patrascu & Thorup 2007]


Even for static queries (no Insert/Delete)
O(1)
• Ω(log log u) time per query for u = n(log n)

• O(n · poly(log n)) space

Space Improvements
We can improve from Θ(u) to O(n log log u).

• Only create nonempty clusters

– If V.min becomes None, deallocate V

• Store V.cluster as a hashtable of nonempty clusters

• Each insert may create a new structure Θ(log log u) times (each empty insert)
ˇ at]
– Can actually happen [Vladimir Cun´

• Charge pointer to structure (and associated hash table entry) to the structure

This gives us O(n log log u) space (but randomized).

Indirection
We can further reduce to O(n) space.

• Store vEB structure with n = O(log log u) using BST or even an array

=⇒ O(log log n) time once in base case

• We use O(n/ log log u) such structures (disjoint)

=⇒ O( log log
n

u · log log u ) = O( n ) space for small

• Larger structures “store” pointers to them

=⇒ O( log log
n
u · log log u ) = O( n ) space for large

• Details: Split/Merge small structures

6
MIT OpenCourseWare
http://ocw.mit.edu

6.046J / 18.410J Design and Analysis of Algorithms


Spring 2015

For information about citing these materials or our Terms of Use, visit: http://ocw.mit.edu/terms.

You might also like