Árbol de boas de Van Emde | Juego 2 | Consultas de inserción, búsqueda, mínimo y máximo

Se recomienda encarecidamente ver primero los artículos anteriores sobre Van Emde Boas Tree.

Procedimiento para insertar

  1. Si no hay claves presentes en el árbol, simplemente asigne el mínimo y el máximo del árbol a la clave.
  2. De lo contrario, profundizaremos en el árbol y haremos lo siguiente:
    • Si la clave que queremos insertar es menor que el mínimo actual del árbol, intercambiamos ambos valores porque la nueva clave será el mínimo real del árbol y la clave que ya estaba en el lugar del mínimo se usará para el proceso posterior. 
      Este concepto se puede considerar como propagación perezosa en Van Emde Boas Tree. Porque este antiguo valor mínimo es realmente un mínimo de uno de los grupos de la estructura recursiva de Van Emde Boas. Así que en realidad no profundizamos en la estructura hasta que surge la necesidad. 
    • Si no estamos en el caso base, significa que el tamaño del universo del árbol es mayor que 2, entonces:
      • Si el clúster del árbol [Alto (clave)] está vacío, llamamos recursivamente a insertar sobre el resumen y, como estamos haciendo una propagación diferida, simplemente asignamos el valor mínimo y máximo a la clave y detenemos la recursión.
      • De lo contrario, llamamos a insertar sobre el clúster en el que está presente la clave.
  3. De manera similar, verificamos el máximo y establecemos la clave como máximo si es mayor que el máximo actual.

La imagen de abajo representa el árbol VEB(4) vacío:

VEB Tree

Ahora insertamos 1, luego simplemente establecerá el mínimo y el máximo del árbol en 1. Puede ver la propagación perezosa de 1:

VEB Tree

Ahora, si insertamos 0, entonces 1 se propagará al primer grupo y cero será el nuevo mínimo: 

VEB

Procedimiento para la consulta isMember

  • En cualquier punto de nuestra búsqueda, si la clave es el mínimo o el máximo del árbol, lo que significa que la clave está presente, entonces devuelve verdadero.
  • Si llegamos al caso base, pero la condición anterior es falsa, entonces la clave no debe estar presente en el árbol, por lo que devuelve verdadero.
  • De lo contrario, llame recursivamente a la función sobre el grupo de la clave, es decir (Alto (clave)) y su posición en el grupo, es decir (Bajo (clave)).
  • Aquí estamos permitiendo que universe_size sea cualquier potencia de 2, de modo que si surge la situación en la que universe_size es menor que el valor clave, devuelva false.

Mínimo y Máximo : Van Emde Boas Tree almacena mínimo y máximo como sus atributos, por lo que podemos devolver su valor si está presente y nulo de lo contrario.
 

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 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));
        }
    }
}
 
// Driver code
int main()
{
    Van_Emde_Boas* veb = new Van_Emde_Boas(8);
 
    // Inserting Keys
    insert(veb, 2);
    insert(veb, 3);
    insert(veb, 6);
 
    cout << boolalpha;
 
    // Checking isMember query
    cout << isMember(veb, 3) << endl;
 
    cout << isMember(veb, 4) << endl;
 
    // Maximum of VEB
    cout << VEB_maximum(veb) << endl;
 
    // Minimum of VEB
    cout << VEB_minimum(veb) << endl;
}
Producción: 

true
false
6
2

 

Publicación traducida automáticamente

Artículo escrito por Aakash_Panchal y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *