A non-intersecting set is a data structure that contains multiple non-intersecting sets. A typical application is to determine the number of connected subgraphs in an undirected graph. Its basic operations include:
Make-set (x): Creates a new set. The set Member is X;
Union (x, y): combines a set that contains x and y into a set;
Find-set (x): returns a pointer to a set containing X;
The following is an example. (a) is an undirected graph, and (B) is the number of connected subgraphs that are obtained by using an unmatched set. In this way, each vertex is regarded as a set, and each edge is traversed to merge the set of edge endpoints. When all edges are processed, the vertex that can be connected is in a set. In this way, four sets are generated. That is, there are four connected subgraphs.
How can we implement a non-intersecting set?
The most intuitive and simple method is to use a linked list: each set is a linked list. When merged, a linked list is connected to the back of another linked list. To support the find-set operation, each element must have a pointer pointing to the header node of the set. To update a linked list, you also need to update this header pointer so that it points to the header of the new set. If we do not consider the size of the Two Sets during merging, the worst case is to connect the long one to the shorter one, so we need to update more header pointers. The simple optimization method is to always connect the short linked list to the long end.
A better way is to use a root tree. If optimization is not performed, the root tree is not much faster than the linked list. However, after two optimizations, namely, merge by rank and compress by path, you can obtain the running time in a linear relationship with the number of operations M.
Merge by rank: the basic idea is similar to optimization during the linked list. When two sets (trees) are to be merged, a small set is merged into a large one. The method used is not to record the size of a set, but to describe it by rank. Rank is an upper bound of the height of the Set tree. In union, the two sets X and Y to be merged. If the rank of X is large, merge y into X: Set the parent node of Y's root to the root of X. At this time, the rank of X does not need to be changed, because the height does not change, it only increases the number of sub-nodes in the root of X, but how can the rank of x and y be the same, then, the parent node of a root is randomly set as another root, but the rank needs to be increased by 1.
Path compression: When you find-set, each node in the search path directly points to its root node, that is, the height of the tree is reduced, the root node has more children. However, these operations do not change the rank size. Therefore, the rank here is only a fuzzy upper bound and does not really represent the height of the tree. The advantage of path compression is that subsequent find-set operations can become faster. In "Find-set (a)", the parent node of all nodes in the search path becomes the root node, then the subsequent find-set (B) can be completed in one step.
The use of non-intersecting sets can still be more flexible. If you encounter a ring problem, you may consider the following: Yong Xing | thinking shares a question:
A zero-indexed array a consisting of n different integers is given. the array contains all integers in the range [0 .. n−1]. sets s [k] For 0 ≤ k <n are defined as follows: s [k] = {A [K], a [A [k], A [A [k],...}. sets s [k] are finite for each K.
Write a function:
Class solution {public int solution (INT [] );}
That, given an array a consisting of n integers, returns the size of the largest set S [k] for this array. The function shocould return 0 if the array is empty.
This problem is also suitable for solving with this non-intersecting set data structure.