It is highly recommended to read the previous articles on Van Emde Boas Tree first.
Procedure for successor:
- Base case: If the size of the tree is 2 then if query-key is 0 and key – 1 is present in the tree then return 1, as it will be the successor. Otherwise, return null.
- If the key is less than minimum then we can easily say that minimum will be the successor of the query-key.
-
Recursive case:
- We first search for the successor in the cluster in which the key is present.
- If we find any successor in the cluster then generate its index and return it.
- Otherwise, search for the next cluster, with at least one key present, in summary, and return the index the minimum of that cluster.
See query for the successor of 0 the in below image:
The below image represents the successor of 1 query over VEB tree containing key 1 & 2:
Procedure for Predecessor:
- Base case: If the size of the tree is 2 then if query-key is 1 and key-0 is present in the tree then return 0, as it will be the predecessor. Otherwise, return null.
- If the key is greater than the maximum then we can easily say that maximum will be the predecessor of the query-key.
-
Recursive case:
- We first search for the predecessor in the cluster in which the key is present.
- If we find any predecessor in the cluster then generate its index and return it.
- Otherwise, search for the previous cluster, with at least one key present, in summary. If any cluster is present then return the index of the maximum of that cluster.
- If no cluster with that property is present then see if due to lazy propagation, the minimum of the tree(In which the cluster is present) is less than the key, if yes then return minimum otherwise return null.
Below image represents query predecessor of key-2:
C++
#include <bits/stdc++.h> using namespace std;
class Van_Emde_Boas {
public :
int universe_size;
int minimum;
int maximum;
Van_Emde_Boas* summary;
vector<Van_Emde_Boas*> 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<Van_Emde_Boas*>(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<Van_Emde_Boas*>(no_clusters, nullptr);
// Assigning VEB(sqrt(u)) to all its clusters
for ( int i = 0; i < no_clusters; i++) {
clusters[i] = new Van_Emde_Boas( ceil ( sqrt (size)));
}
}
}
}; // Function to return the minimum value // from the tree if it exists int VEB_minimum(Van_Emde_Boas* helper)
{ return (helper->minimum == -1 ? -1 : helper->minimum);
} // Function to return the maximum value // from the tree if it exists int VEB_maximum(Van_Emde_Boas* helper)
{ return (helper->maximum == -1 ? -1 : helper->maximum);
} // Function to insert a key in the tree void insert(Van_Emde_Boas* helper, int key)
{ // If no key is present in the tree
// then set both minimum and maximum
// to the key (Read the previous article
// for more understanding about it)
if (helper->minimum == -1) {
helper->minimum = key;
helper->maximum = key;
}
else {
if (key < helper->minimum) {
// If the key is less than the current minimum
// then swap it with the current minimum
// because this minimum is actually
// minimum of one of the internal cluster
// so as we go deeper into the Van Emde Boas
// we need to take that minimum to its real position
// This concept is similar to "Lazy Propagation"
swap(helper->minimum, key);
}
// Not base case then...
if (helper->universe_size > 2) {
// If no key is present in the cluster then insert key into
// both cluster and summary
if (VEB_minimum(helper->clusters[helper->high(key)]) == -1) {
insert(helper->summary, helper->high(key));
// Sets the minimum and maximum of cluster to the key
// as no other keys are present we will stop at this level
// we are not going deeper into the structure like
// Lazy Propagation
helper->clusters[helper->high(key)]->minimum = helper->low(key);
helper->clusters[helper->high(key)]->maximum = helper->low(key);
}
else {
// If there are other elements in the tree then recursively
// go deeper into the structure to set attributes accordingly
insert(helper->clusters[helper->high(key)], helper->low(key));
}
}
// Sets the key as maximum it is greater than current maximum
if (key > helper->maximum) {
helper->maximum = key;
}
}
} // Function that returns true if the // key is present in the tree bool isMember(Van_Emde_Boas* helper, int key)
{ // If universe_size is less than the key
// then we can not search the key so returns
// false
if (helper->universe_size < key) {
return false ;
}
// If at any point of our traversal
// of the tree if the key is the minimum
// or the maximum of the subtree, then
// the key is present so returns true
if (helper->minimum == key || helper->maximum == key) {
return true ;
}
else {
// If after attending above condition,
// if the size of the tree is 2 then
// the present key must be
// maximum or minimum of the tree if it
// is not then it returns false because key
// can not be present in the sub tree
if (helper->universe_size == 2) {
return false ;
}
else {
// Recursive call over the cluster
// in which the key can be present
// and also pass the new position of the key
// i.e., low(key)
return isMember(helper->clusters[helper->high(key)],
helper->low(key));
}
}
} // Function to find the successor of the given key int VEB_successor(Van_Emde_Boas* helper, int key)
{ // Base case: If key is 0 and its successor
// is present then return 1 else return null
if (helper->universe_size == 2) {
if (key == 0 && helper->maximum == 1) {
return 1;
}
else {
return -1;
}
}
// If key is less then minimum then return minimum
// because it will be successor of the key
else if (helper->minimum != -1 && key < helper->minimum) {
return helper->minimum;
}
else {
// Find successor inside the cluster of the key
// First find the maximum in the cluster
int max_incluster = VEB_maximum(helper->clusters[helper->high(key)]);
int offset{ 0 }, succ_cluster{ 0 };
// If there is any key( maximum!=-1 ) present in the cluster then find
// the successor inside of the cluster
if (max_incluster != -1 && helper->low(key) < max_incluster) {
offset = VEB_successor(helper->clusters[helper->high(key)],
helper->low(key));
return helper->generate_index(helper->high(key), offset);
}
// Otherwise look for the next cluster with at least one key present
else {
succ_cluster = VEB_successor(helper->summary, helper->high(key));
// If there is no cluster with any key present
// in summary then return null
if (succ_cluster == -1) {
return -1;
}
// Find minimum in successor cluster which will
// be the successor of the key
else {
offset = VEB_minimum(helper->clusters[succ_cluster]);
return helper->generate_index(succ_cluster, offset);
}
}
}
} // Function to find the predecessor of the given key int VEB_predecessor(Van_Emde_Boas* helper, int key)
{ // Base case: If the key is 1 and it's predecessor
// is present then return 0 else return null
if (helper->universe_size == 2) {
if (key == 1 && helper->minimum == 0) {
return 0;
}
else
return -1;
}
// If the key is greater than maximum of the tree then
// return key as it will be the predecessor of the key
else if (helper->maximum != -1 && key > helper->maximum) {
return helper->maximum;
}
else {
// Find predecessor in the cluster of the key
// First find minimum in the key to check whether any key
// is present in the cluster
int min_incluster = VEB_minimum(helper->clusters[helper->high(key)]);
int offset{ 0 }, pred_cluster{ 0 };
// If any key is present in the cluster then find predecessor in
// the cluster
if (min_incluster != -1 && helper->low(key) > min_incluster) {
offset = VEB_predecessor(helper->clusters[helper->high(key)],
helper->low(key));
return helper->generate_index(helper->high(key), offset);
}
// Otherwise look for predecessor in the summary which
// returns the index of predecessor cluster with any key present
else {
pred_cluster = VEB_predecessor(helper->summary, helper->high(key));
// If no predecessor cluster then...
if (pred_cluster == -1) {
// Special case which is due to lazy propagation
if (helper->minimum != -1 && key > helper->minimum) {
return helper->minimum;
}
else
return -1;
}
// Otherwise find maximum in the predecessor cluster
else {
offset = VEB_maximum(helper->clusters[pred_cluster]);
return helper->generate_index(pred_cluster, offset);
}
}
}
} // Driver code int main()
{ Van_Emde_Boas* veb = new Van_Emde_Boas(8);
// Inserting Keys
insert(veb, 2);
insert(veb, 3);
insert(veb, 4);
insert(veb, 6);
// Queries
cout << VEB_successor(veb, 2) << endl;
cout << VEB_predecessor(veb, 6) << endl;
cout << VEB_successor(veb, 4) << endl;
return 0;
} |
Java
import java.util.*;
class Van_Emde_Boas {
public int universe_size;
public int minimum;
public int maximum;
public Van_Emde_Boas summary;
public ArrayList<Van_Emde_Boas> clusters;
public Van_Emde_Boas( int size)
{
universe_size = size;
minimum = - 1 ;
maximum = - 1 ;
// Base case
if (size <= 2 ) {
summary = null ;
clusters = new ArrayList<Van_Emde_Boas>( 0 );
}
else {
int no_clusters
= ( int )Math.ceil(Math.sqrt(size));
summary = new Van_Emde_Boas(no_clusters);
clusters
= new ArrayList<Van_Emde_Boas>(no_clusters);
for ( int i = 0 ; i < no_clusters; i++) {
clusters.add( new Van_Emde_Boas(
( int )Math.ceil(Math.sqrt(size))));
}
}
}
// Function to return cluster numbers
// in which key is present
public int high( int x)
{
int div = ( int )Math.ceil(Math.sqrt(universe_size));
return x / div;
}
// Function to return position of x in cluster
public int low( int x)
{
int mod = ( int )Math.ceil(Math.sqrt(universe_size));
return x % mod;
}
// Function to return position of x in cluster
public int generate_index( int x, int y)
{
int ru = ( int )Math.ceil(Math.sqrt(universe_size));
return x * ru + y;
}
} class Main {
// Function to return the minimum value
// from the tree if it exists
public static int VEB_minimum(Van_Emde_Boas helper)
{
return (helper.minimum == - 1 ? - 1 : helper.minimum);
}
// Function to return the maximum value
// from the tree if it exists
public static int VEB_maximum(Van_Emde_Boas helper)
{
return (helper.maximum == - 1 ? - 1 : helper.maximum);
}
// Function to insert a key in the tree
static void insert(Van_Emde_Boas helper, int key)
{
// If no key is present in the tree
// then set both minimum and maximum
// to the key (Read the previous article
// for more understanding about it)
if (helper.minimum == - 1 ) {
helper.minimum = key;
helper.maximum = key;
}
else {
// If the key is less than the current minimum
// then swap it with the current minimum
// because this minimum is actually
// minimum of one of the internal cluster
if (key < helper.minimum) {
int temp = helper.minimum;
helper.minimum = key;
key = temp;
}
// Not base case then...
if (helper.universe_size > 2 ) {
// If no key is present in the cluster then
// insert key into both cluster and summary
if (VEB_minimum(helper.clusters.get(
helper.high(key)))
== - 1 ) {
insert(helper.summary,
helper.high(key));
// Sets the minimum and maximum of
// cluster to the key as no other keys
// are present we will stop at this
// level
helper.clusters.get(helper.high(key))
.minimum
= helper.low(key);
helper.clusters.get(helper.high(key))
.maximum
= helper.low(key);
}
else {
// If there are other elements in the
// tree then recursively go deeper into
// the structure to set attributes
// accordingly
insert(helper.clusters.get(
helper.high(key)),
helper.low(key));
}
}
// Sets the key as maximum it is greater than
// current maximum
if (key > helper.maximum) {
helper.maximum = key;
}
}
}
// Function to find the successor of the given key
public static int VEB_successor(Van_Emde_Boas helper,
int key)
{
if (helper.universe_size == 2 ) {
if (key == 0 && helper.maximum == 1 ) {
return 1 ;
}
else {
return - 1 ;
}
}
// If key is less then minimum then return minimum
// because it will be successor of the key
else if (helper.minimum != - 1
&& key < helper.minimum) {
return helper.minimum;
}
else {
// Find successor inside the cluster of the key
// First find the maximum in the cluster
int max_incluster = VEB_maximum(
helper.clusters.get(helper.high(key)));
int offset = 0 ;
int succ_cluster = 0 ;
// If there is any key( maximum!=-1 ) present in
// the cluster then find the successor inside of
// the cluster
if (max_incluster != - 1
&& helper.low(key) < max_incluster) {
offset = VEB_successor(
helper.clusters.get(helper.high(key)),
helper.low(key));
return helper.generate_index(
helper.high(key), offset);
}
else {
succ_cluster = VEB_successor(
helper.summary, helper.high(key));
if (succ_cluster == - 1 ) {
return - 1 ;
}
// Find minimum in successor cluster which
// will be the successor of the key
else {
offset = VEB_minimum(
helper.clusters.get(succ_cluster));
return helper.generate_index(
succ_cluster, offset);
}
}
}
}
// Function to find the predecessor of the given key
public static int VEB_predecessor(Van_Emde_Boas helper,
int key)
{
if (helper.universe_size == 2 ) {
if (key == 1 && helper.minimum == 0 ) {
return 0 ;
}
else {
return - 1 ;
}
}
// If the key is greater than maximum of the tree
// then
// return key as it will be the predecessor of the
// key
else if (helper.maximum != - 1
&& key > helper.maximum) {
return helper.maximum;
}
else {
// Find predecessor in the cluster of the key
// First find minimum in the key to check
// whether any key is present in the cluster
int min_incluster = VEB_minimum(
helper.clusters.get(helper.high(key)));
int offset = 0 ;
int pred_cluster = 0 ;
// If any key is present in the cluster then
// find predecessor in the cluster
if (min_incluster != - 1
&& helper.low(key) > min_incluster) {
offset = VEB_predecessor(
helper.clusters.get(helper.high(key)),
helper.low(key));
return helper.generate_index(
helper.high(key), offset);
}
else {
// returns the index of predecessor cluster
// with any key present
pred_cluster = VEB_predecessor(
helper.summary, helper.high(key));
// If no predecessor cluster then...
if (pred_cluster == - 1 ) {
if (helper.minimum != - 1
&& key > helper.minimum) {
return helper.minimum;
}
else {
return - 1 ;
}
} // Otherwise find maximum in the
// predecessor cluster
else {
offset = VEB_maximum(
helper.clusters.get(pred_cluster));
return helper.generate_index(
pred_cluster, offset);
}
}
}
}
// Driver code
public static void main(String[] args)
{
Van_Emde_Boas veb = new Van_Emde_Boas( 8 );
insert(veb, 2 );
insert(veb, 3 );
insert(veb, 4 );
insert(veb, 6 );
System.out.println(VEB_successor(veb, 2 ));
System.out.println(VEB_predecessor(veb, 6 ));
System.out.println(VEB_successor(veb, 4 ));
}
} |
Python3
import math
class Van_Emde_Boas:
# Constructor
def __init__( self , size):
self .universe_size = size
self .minimum = None
self .maximum = None
if size < = 2 :
self .summary = None
self .clusters = [ None ] * 0
else :
no_clusters = math.ceil(math.sqrt(size))
self .summary = Van_Emde_Boas(no_clusters)
self .clusters = [Van_Emde_Boas(
math.ceil(math.sqrt(size))) for i in range (no_clusters)]
# Function to return cluster numbers
# in which key is present
def high( self , x):
div = math.ceil(math.sqrt( self .universe_size))
return x / / div
def low( self , x):
mod = math.ceil(math.sqrt( self .universe_size))
return x % mod
# Function to return the index from
# cluster number and position
def generate_index( self , x, y):
ru = math.ceil(math.sqrt( self .universe_size))
return (x or 0 ) * ru + (y or 0 )
# Function to return the minimum value # from the tree if it exists def VEB_minimum(helper):
return helper.minimum
# Function to return the maximum value # from the tree if it exists def VEB_maximum(helper):
return helper.maximum
# Function to insert a key in the tree def insert(helper, key):
# If no key is present in the tree
# then set both minimum and maximum
# to the key (Read the previous article
# for more understanding about it)
if helper.minimum is None :
helper.minimum = key
helper.maximum = key
else :
if key < helper.minimum:
# If the key is less than the current minimum
# then swap it with the current minimum
# because this minimum is actually
# minimum of one of the internal cluster
# so as we go deeper into the Van Emde Boas
# we need to take that minimum to its real position
# This concept is similar to "Lazy Propagation"
helper.minimum, key = key, helper.minimum
if helper.universe_size > 2 :
if VEB_minimum(helper.clusters[helper.high(key)]) is None :
insert(helper.summary, helper.high(key))
# Sets the minimum and maximum of cluster to the key
# as no other keys are present we will stop at this level
# we are not going deeper into the structure like
# Lazy Propagation
helper.clusters[helper.high(key)].minimum = helper.low(key)
helper.clusters[helper.high(key)].maximum = helper.low(key)
else :
# If there are other elements in the tree then recursively
# go deeper into the structure to set attributes accordingly
insert(helper.clusters[helper.high(key)], helper.low(key))
if key > helper.maximum:
helper.maximum = key
# Function to find the successor of the given key def VEB_successor(helper, x):
# Base case: If key is 0 and its successor
# is present then return 1 else return null
if helper.universe_size = = 2 :
if x = = 0 and helper.maximum = = 1 :
return 1
else :
return None
# If key is less then minimum then return minimum
# because it will be successor of the key
elif helper.minimum is not None and x < helper.minimum:
return helper.minimum
else :
# Find successor inside the cluster of the key
# First find the maximum in the cluster
max_in_cluster = VEB_maximum(helper.clusters[helper.high(x)])
# If there is any key( maximum!=-1 ) present in the cluster then find
# the successor inside of the cluster
if max_in_cluster is not None and helper.low(x) < max_in_cluster:
offset = VEB_successor(helper.clusters[helper.high(x)], helper.low(x))
return helper.generate_index(helper.high(x), offset)
# Otherwise look for the next cluster with at least one key present
else :
succ_cluster = VEB_successor(helper.summary, helper.high(x))
# If there is no cluster with any key present
# in summary then return null
if succ_cluster is None :
return None
# Find minimum in successor cluster which will
# be the successor of the key
else :
offset = VEB_minimum(helper.clusters[succ_cluster])
return helper.generate_index(succ_cluster, offset)
# Function to find the predecessor of the given key def VEB_predecessor(helper, x):
# Base case: If the key is 1 and it's predecessor
# is present then return 0 else return null
if helper.universe_size = = 2 :
if x = = 1 and helper.minimum = = 0 :
return 0
else :
return None
# If the key is greater than maximum of the tree then
# return key as it will be the predecessor of the key
elif helper.maximum is not None and x > helper.maximum:
return helper.maximum
else :
# Find predecessor in the cluster of the key
# First find minimum in the key to check whether any key
# is present in the cluster
min_in_cluster = VEB_minimum(helper.clusters[helper.high(x)])
# If any key is present in the cluster then find predecessor in
# the cluster
if min_in_cluster is not None and helper.low(x) > min_in_cluster:
offset = VEB_predecessor(helper.clusters[helper.high(x)], helper.low(x))
return helper.generate_index(helper.high(x), offset)
# Otherwise look for predecessor in the summary which
# returns the index of predecessor cluster with any key present
else :
pred_cluster = VEB_predecessor(helper.summary, helper.high(x))
# If no predecessor cluster then...
if pred_cluster is None :
# Special case which is due to lazy propagation
if helper.minimum is not None and x > helper.minimum:
return helper.minimum
else :
return None
# Otherwise find maximum in the predecessor cluster
else :
offset = VEB_maximum(helper.clusters[pred_cluster])
return helper.generate_index(pred_cluster, offset)
# Driver code veb = Van_Emde_Boas( 6 )
# Inserting keys insert(veb, 2 )
insert(veb, 3 )
insert(veb, 4 )
insert(veb, 6 )
print (VEB_successor(veb, 2 ))
print (VEB_predecessor(veb, 6 ))
print (VEB_successor(veb, 4 ))
|
C#
using System;
using System.Collections.Generic;
public class Van_Emde_Boas {
public int universe_size;
public int minimum;
public int maximum;
public Van_Emde_Boas summary;
public List<Van_Emde_Boas> clusters;
public Van_Emde_Boas( int size)
{
universe_size = size;
minimum = -1;
maximum = -1;
// Base case
if (size <= 2) {
summary = null ;
clusters = new List<Van_Emde_Boas>(0);
}
else {
int no_clusters
= ( int )Math.Ceiling(Math.Sqrt(size));
summary = new Van_Emde_Boas(no_clusters);
clusters
= new List<Van_Emde_Boas>(no_clusters);
for ( int i = 0; i < no_clusters; i++) {
clusters.Add( new Van_Emde_Boas(
( int )Math.Ceiling(Math.Sqrt(size))));
}
}
}
// Function to return cluster numbers
// in which key is present
public int high( int x)
{
int div = ( int )Math.Ceiling(Math.Sqrt(universe_size));
return x / div;
}
// Function to return position of x in cluster
public int low( int x)
{
int mod = ( int )Math.Ceiling(Math.Sqrt(universe_size));
return x % mod;
}
// Function to return position of x in cluster
public int generate_index( int x, int y)
{
int ru = ( int )Math.Ceiling(Math.Sqrt(universe_size));
return x * ru + y;
}
} public class Main_Program {
// Function to return the minimum value
// from the tree if it exists
public static int VEB_minimum(Van_Emde_Boas helper)
{
return (helper.minimum == -1 ? -1 : helper.minimum);
}
// Function to return the maximum value
// from the tree if it exists
public static int VEB_maximum(Van_Emde_Boas helper)
{
return (helper.maximum == -1 ? -1 : helper.maximum);
}
// Function to insert a key in the tree
static void insert(Van_Emde_Boas helper, int key)
{
// If no key is present in the tree
// then set both minimum and maximum
// to the key (Read the previous article
// for more understanding about it)
if (helper.minimum == -1) {
helper.minimum = key;
helper.maximum = key;
}
else {
// If the key is less than the current minimum
// then swap it with the current minimum
// because this minimum is actually
// minimum of one of the internal cluster
if (key < helper.minimum) {
int temp = helper.minimum;
helper.minimum = key;
key = temp;
}
// Not base case then...
if (helper.universe_size > 2) {
// If no key is present in the cluster then
// insert key into both cluster and summary
if (VEB_minimum(helper.clusters[helper.high(key)])
== -1) {
insert(helper.summary,
helper.high(key));
// Sets the minimum and maximum of
// cluster to the key as no other keys
// are present we will stop at this
// level
helper.clusters[helper.high(key)]
.minimum
= helper.low(key);
helper.clusters[helper.high(key)]
.maximum
= helper.low(key);
}
else {
// If there are other elements in the
// tree then recursively go deeper into
// the structure to set attributes
// accordingly
insert(helper.clusters[
helper.high(key)],
helper.low(key));
}
}
// Sets the key as maximum it is greater than
// current maximum
if (key > helper.maximum) {
helper.maximum = key;
}
}
}
// Function to find the successor of the given key public static int VEB_successor(Van_Emde_Boas helper, int key)
{ if (helper.universe_size == 2)
{
if (key == 0 && helper.maximum == 1)
{
return 1;
}
else
{
return -1;
}
}
// If key is less then minimum then return minimum
// because it will be successor of the key
else if (helper.minimum != -1 && key < helper.minimum)
{
return helper.minimum;
}
else
{
// Find successor inside the cluster of the key
// First find the maximum in the cluster
int max_incluster = VEB_maximum(helper.clusters[helper.high(key)]);
int offset = 0;
int succ_cluster = 0;
// If there is any key( maximum!=-1 ) present in
// the cluster then find the successor inside of
// the cluster
if (max_incluster != -1 && helper.low(key) < max_incluster)
{
offset = VEB_successor(helper.clusters[helper.high(key)], helper.low(key));
return helper.generate_index(helper.high(key), offset);
}
else
{
succ_cluster = VEB_successor(helper.summary, helper.high(key));
if (succ_cluster == -1)
{
return -1;
}
else
{
// Find minimum in successor cluster which
// will be the successor of the key
offset = VEB_minimum(helper.clusters[succ_cluster]);
return helper.generate_index(succ_cluster, offset);
}
}
}
} // Function to find the predecessor of the given key
public static int VEB_predecessor(Van_Emde_Boas helper, int key) {
if (helper.universe_size == 2) {
if (key == 1 && helper.minimum == 0) {
return 0;
}
else {
return -1;
}
}
// If the key is greater than maximum of the tree
// then
// return key as it will be the predecessor of the
// key
else if (helper.maximum != -1 && key > helper.maximum) {
return helper.maximum;
}
else {
// Find predecessor in the cluster of the key
// First find minimum in the key to check
// whether any key is present in the cluster
int min_incluster = VEB_minimum(helper.clusters[helper.high(key)]);
int offset = 0;
int pred_cluster = 0;
// If any key is present in the cluster then
// find predecessor in the cluster
if (min_incluster != -1 && helper.low(key) > min_incluster) {
offset = VEB_predecessor(
helper.clusters[helper.high(key)],
helper.low(key));
return helper.generate_index(helper.high(key), offset);
}
else {
// returns the index of predecessor cluster
// with any key present
pred_cluster = VEB_predecessor(
helper.summary, helper.high(key));
if (pred_cluster == -1) {
if (helper.minimum != -1 && key > helper.minimum) {
return helper.minimum;
}
else {
return -1;
}
}
// Otherwise find maximum in the
// predecessor cluster
else {
offset = VEB_maximum(helper.clusters[pred_cluster]);
return helper.generate_index(pred_cluster, offset);
}
}
}
}
// Driver code
public static void Main() {
Van_Emde_Boas veb = new Van_Emde_Boas(8);
insert(veb, 2);
insert(veb, 3);
insert(veb, 4);
insert(veb, 6);
Console.WriteLine(VEB_successor(veb, 2));
Console.WriteLine(VEB_predecessor(veb, 6));
Console.WriteLine(VEB_successor(veb, 4));
}
} |
Javascript
class VanEmdeBoas { constructor(size) {
this .universe_size = size;
this .minimum = -1;
this .maximum = -1;
this .summary = null ;
this .clusters = [];
if (size <= 2) {
this .summary = null ;
this .clusters = new Array(0).fill( null );
} else {
const no_clusters = Math.ceil(Math.sqrt(size));
this .summary = new VanEmdeBoas(no_clusters);
this .clusters = new Array(no_clusters).fill( null );
for (let i = 0; i < no_clusters; i++) {
this .clusters[i] = new VanEmdeBoas(Math.ceil(Math.sqrt(size)));
}
}
}
high(x) {
const div = Math.ceil(Math.sqrt( this .universe_size));
return Math.floor(x / div);
}
low(x) {
const mod = Math.ceil(Math.sqrt( this .universe_size));
return x % mod;
}
generate_index(x, y) {
const ru = Math.ceil(Math.sqrt( this .universe_size));
return x * ru + y;
}
} function VEB_minimum(helper) {
return helper.minimum === -1 ? -1 : helper.minimum;
} function VEB_maximum(helper) {
return helper.maximum === -1 ? -1 : helper.maximum;
} function insert(helper, key) {
if (helper.minimum === -1) {
helper.minimum = key;
helper.maximum = key;
} else {
if (key < helper.minimum) {
[helper.minimum, key] = [key, helper.minimum];
}
if (helper.universe_size > 2) {
if (VEB_minimum(helper.clusters[helper.high(key)]) === -1) {
insert(helper.summary, helper.high(key));
helper.clusters[helper.high(key)].minimum = helper.low(key);
helper.clusters[helper.high(key)].maximum = helper.low(key);
} else {
insert(helper.clusters[helper.high(key)], helper.low(key));
}
}
if (key > helper.maximum) {
helper.maximum = key;
}
}
} function isMember(helper, key) {
if (helper.universe_size < key) {
return false ;
}
if (helper.minimum === key || helper.maximum === key) {
return true ;
}
if (helper.universe_size === 2) {
return false ;
}
return isMember(helper.clusters[helper.high(key)], helper.low(key));
} function VEB_successor(helper, key) {
if (helper.universe_size === 2) {
if (key === 0 && helper.maximum === 1) {
return 1;
} else {
return -1;
}
}
if (helper.minimum !== -1 && key < helper.minimum) {
return helper.minimum;
}
const max_incluster = VEB_maximum(helper.clusters[helper.high(key)]);
let offset = 0;
let succ_cluster = 0;
if (max_incluster !== -1 && helper.low(key) < max_incluster) {
offset = VEB_successor(helper.clusters[helper.high(key)], helper.low(key));
return helper.generate_index(helper.high(key), offset);
}
succ_cluster = VEB_successor(helper.summary, helper.high(key));
if (succ_cluster === -1) {
return -1;
}
offset = VEB_minimum(helper.clusters[succ_cluster]);
return helper.generate_index(succ_cluster, offset);
} function VEB_predecessor(helper, key) {
if (helper.universe_size === 2) {
if (key === 1 && helper.minimum === 0) {
return 0;
} else {
return -1;
}
}
if (helper.maximum !== -1 && key > helper.maximum) {
return helper.maximum;
}
const min_incluster = VEB_minimum(helper.clusters[helper.high(key)]);
let offset = 0;
let pred_cluster = 0;
if (min_incluster !== -1 && helper.low(key) > min_incluster) {
offset = VEB_predecessor(helper.clusters[helper.high(key)], helper.low(key));
return helper.generate_index(helper.high(key), offset);
}
pred_cluster = VEB_predecessor(helper.summary, helper.high(key));
if (pred_cluster === -1) {
if (helper.minimum !== -1 && key > helper.minimum) {
return helper.minimum;
} else {
return -1;
}
}
offset = VEB_maximum(helper.clusters[pred_cluster]);
return helper.generate_index(pred_cluster, offset);
} const veb = new VanEmdeBoas(8);
insert(veb, 2); insert(veb, 3); insert(veb, 4); insert(veb, 6); console.log(VEB_successor(veb, 2)); console.log(VEB_predecessor(veb, 6)); console.log(VEB_successor(veb, 4)); |
Output
3 4 6
Time Complexity: O(log2(u)*log2(log2(u))) per query
Auxiliary Space: O(N).
Recommended Articles
25. Successor Graph