Union-find fast merging (Java example code)

Table of contents

 

Quick merge of union search set

Java example code

UnionFind2.java file code:


 

Quick merge of union search set

For a set of data, union query mainly supports two actions:

  • union(p,q) - joins two elements p and q.

  • find(p) - Query the collection in which element p is located.

  • isConnected(p,q) - Check whether two elements p and q are connected together.

In the previous section, we expressed the union search in the form of an id array. The time complexity of the search during the actual operation was O(1) , but the connection efficiency was not high.

In this section, we will use another way to implement and search the set. Treat each element as a node and point to its parent node, and the root node points to itself. As shown in the figure below, node 3 points to node 2, which means that 3 and 2 are connected together. Node 2 itself is the root node, so it points to itself.

 

0eaff4abe708edb1c4ccb073435b4cf4.png

The same array is used to represent the set, but the following set of elements uses parent to represent the parent node pointed by the current element. Each element points to itself and is independent.

 

502a87cfa071533d4e522a92380ad148.png

 

31bcc36aa1bd6f328576513780cca5b6.png

If union(4,3) is operated at this time, element 4 points to element 3:

 

e2ac0ffc77b6be45caa3de502dff8e1e.png

The array is also changed accordingly:

 

4ffe9667dd5d1504c7a1a0867e47bd17.png

To determine whether two elements are connected, you only need to determine whether the root nodes are the same.

As shown in the figure below, the root nodes of node 4 and node 9 are both 8, so they are connected.

 

8e3785cecfeaef04688311e354a3a3d4.png

To connect two elements, you only need to find their corresponding root nodes and connect the root nodes, then they are connected nodes.

Assume that to connect 6 and 4 in the above figure, you only need to point the root node 5 of 6 to the root node 8 of 4.

 

82b6a5d96df1a4bd63c1c8dd2bc6d5b6.png

To build this kind of tree structure pointing to the parent node, use an array to build a tree pointing to the parent node. parent[i] represents the parent node pointed to by the i element.

...
private int[] parent;
private int count; // Number of data
...

The search process is to find the set number corresponding to element p, and continue to query its parent node until it reaches the root node. The characteristics of the root node are parent[p] == p, O(h) complexity, h is the height of the tree.

...
private int find(int p){
    assert( p >= 0 && p < count );
    while( p != parent[p] )
        p = parent[p];
    return p;
}
...

Merge the sets to which element p and element q belong, query the root nodes of the two elements respectively, and make one of the root nodes point to the other root node, and the two sets are merged. This operation has a time complexity of O(h), where h is the height of the tree.

public void unionElements ( int p , int q ) {     int pRoot = find ( p ) ;     int qRoot = find(q);     if ( pRoot == qRoot )         return ;     parent [ pRoot ] = qRoot ; } }





Java example code

Source code package download: Download

UnionFind2.java file code:

package runoob.union;
/**
 * The second version of unionFind
 */
public class UnionFind2 {     // Our second version of Union-Find, uses an array to build a tree pointing to the parent node     // parent[i] represents the first The parent node pointed to by elements     private int[] parent;     private int count; // Number of data     // Constructor     public UnionFind2(int count){         parent = new int[count];         this.count = count;         // Initialization , each parent[i] points to itself, indicating that each element forms a set of its own         for ( int i = 0 ; i < count ; i ++ )             parent[i] = i;     }     // Search process, find element p The corresponding set number     // O(h) complexity, h is the height of the tree     private int find(int p){         assert( p >= 0 && p < count );
















        // Keep querying its parent node until it reaches the root node
        // Characteristics of the root node: parent[p] == p
        while( p != parent[p] )
            p = parent[p];
        return p;
    }
    / / Check whether element p and element q belong to a set
    // O(h) complexity, h is the height of the tree
    public boolean isConnected( int p , int q ){         return find(p) == find(q);     }     / / Merge the sets to which element p and element q belong     // O(h) complexity, h is the height of the tree     public void unionElements(int p, int q){         int pRoot = find(p);         int qRoot = find(q) ;         if( pRoot == qRoot )             return;         parent[pRoot] = qRoot;     } }











 

Guess you like

Origin blog.csdn.net/2301_78835635/article/details/132322269