Tabla de contenido
Fusión rápida del conjunto de búsqueda sindical
Código del archivo UnionFind2.java:
Fusión rápida del conjunto de búsqueda sindical
Para un conjunto de datos, la consulta de unión admite principalmente dos acciones:
-
union(p,q) - une dos elementos p y q.
-
find(p): consulta la colección en la que se encuentra el elemento p.
-
isConnected(p,q): comprueba si dos elementos p y q están conectados entre sí.
En la sección anterior, expresamos la búsqueda de unión en forma de una matriz de identificación. La complejidad temporal de la búsqueda durante la operación real fue O (1) , pero la eficiencia de la conexión no fue alta.
En esta sección, usaremos otra forma de implementar y buscar el conjunto. Trate cada elemento como un nodo y apunte a su nodo padre, y el nodo raíz apunta a sí mismo. Como se muestra en la figura siguiente, el nodo 3 apunta al nodo 2, lo que significa que 3 y 2 están conectados entre sí. El nodo 2 en sí es el nodo raíz, por lo que apunta a sí mismo.
Se usa la misma matriz para representar el conjunto, pero el siguiente conjunto de elementos usa parent para representar el nodo padre señalado por el elemento actual. Cada elemento apunta a sí mismo y es independiente.
Si se opera union(4,3) en este momento, el elemento 4 apunta al elemento 3:
La matriz también se cambia en consecuencia:
Para determinar si dos elementos están conectados, solo necesita determinar si los nodos raíz son iguales.
Como se muestra en la figura siguiente, los nodos raíz del nodo 4 y del nodo 9 son 8, por lo que están conectados.
Para conectar dos elementos, solo necesita encontrar sus nodos raíz correspondientes y conectar los nodos raíz, entonces son nodos conectados.
Supongamos que para conectar 6 y 4 en la figura anterior, solo necesita apuntar el nodo raíz 5 de 6 al nodo raíz 8 de 4.
Para construir este tipo de estructura de árbol que apunte al nodo principal, use una matriz para construir un árbol que apunte al nodo principal.parent[i] representa el nodo principal al que apunta el elemento i.
...
privado int[] padre;
privado int recuento; // Número de datos
...
El proceso de búsqueda consiste en encontrar el número de conjunto correspondiente al elemento p y continuar consultando su nodo padre hasta llegar al nodo raíz. Las características del nodo raíz son padre [p] == p, complejidad O (h), h es la altura del árbol.
...
privado int buscar(int p){ afirmar( p >= 0 && p <cuenta); mientras( p != padre[p] ) p = padre[p]; devolver p; } ...
Fusione los conjuntos a los que pertenecen el elemento p y el elemento q, consulte los nodos raíz de los dos elementos respectivamente y haga que uno de los nodos raíz apunte al otro nodo raíz, y los dos conjuntos se fusionan. Esta operación tiene una complejidad temporal de O(h), donde h es la altura del árbol.
elementos de unión públicos vacíos (int p, int q) { int pRoot = buscar (p); int qRoot = buscar(q); si (pRoot == qRoot) regresa; padre [pRoot] = qRoot; } }
Código de ejemplo de Java
Descarga del paquete de código fuente: Descargar
Código del archivo UnionFind2.java:
paquete runoob.union;
/**
* La segunda versión de unionFind
*/
public class UnionFind2 { // Nuestra segunda versión de Union-Find utiliza una matriz para construir un árbol que apunte al nodo principal // parent[i] representa el primero El nodo padre al que apuntan los elementos private int[] parent; private int count; // Número de datos // Constructor public UnionFind2(int count){ parent = new int[count]; this.count = count; // Inicialización , cada padre [i] apunta a sí mismo, lo que indica que cada elemento forma un conjunto propio for ( int i = 0 ; i < count ; i ++ ) parent[i] = i; } // Proceso de búsqueda, encontrar elemento p El número de conjunto correspondiente // Complejidad O (h), h es la altura del árbol private int find(int p){ afirmar( p >= 0 && p < count );
// Sigue consultando su nodo padre hasta que llegue al nodo raíz
// Características del nodo raíz: parent[p] == p
while( p != parent[p] )
p = parent[p];
return p;
}
/ / Comprobar si el elemento p y el elemento q pertenecen a un conjunto
// Complejidad O(h), h es la altura del árbol
public boolean isConnected( int p , int q ){ return find(p) == find(q); } // Fusionar los conjuntos a los que pertenecen el elemento p y el elemento q // Complejidad O(h), h es la altura del árbol public void unionElements(int p, int q){ int pRoot = find(p); int qRoot = encontrar(q); si(pRoot == qRoot) retorno; padre[pRoot] = qRoot; } }