Se recomienda encarecidamente ver primero los artículos anteriores sobre Van Emde Boas Tree.
Procedimiento para insertar :
- Si no hay claves presentes en el árbol, simplemente asigne el mínimo y el máximo del árbol a la clave.
- 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.
- 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.
- 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:
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:
Ahora, si insertamos 0, entonces 1 se propagará al primer grupo y cero será el nuevo mínimo:
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; }
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