A collection of S, an element in the collection, A. The equivalence class for a is a subset of S, which contains all elements that are related to a.
Equivalence class formation is a division of S and each member of S appears in an equivalence class. So, judging whether a and B are related,
It is only necessary to determine whether a and B are in an equivalence class.
For the set S division, take any two equivalence classes, Si and Sj, if SI∩SJ =∅, it is said that these sets do not intersect.
For disjoint sets, there are two operations, union/find operations. The find operation is looking for a collection (equivalent class) name that contains the given element.
Union combines two equivalence classes into a new equivalence class.
- Data structure: A tree is used to represent each set (equivalence class) because the elements on the tree have a common root.
Union (x, Y), combining x, y into a new equivalence class, and × as the root.
Union (5,6)
Union (7,8)
Union (5,7)
In this way, the worst case scenario is to build a tree with a height of N-1, that is, Union (7,8), Union (6,7), Union (5,6) ...
This allows the find operation to locate the root of the tree under N-1 operation time O (N)
The above forest is represented by an array of 1-8 elements corresponding to the value representing its father, for example, element 8 corresponds to a value of 7, indicating that its father is 7.
A value of 5 corresponds to 0, which means that 5 is itself a root.
The root of the tree is a recursive process, such as: Find (8), Father 7, execute find (7), Father 5, execute find (5), the corresponding value is 0, indicating that 5 is the root, the end of recursion,
This means that the root of the 8 equivalent class is found to be 5. Determine if 6,8 is related, that is, find (8) = = Find (6) is established.
1typedefintSetType; 2typedefintElementType; 3typedefint*Disjset; 4 5Disjset Initialize (intNum)6 { 7Disjset S =NewSettype[num +1]; 8 9 for(inti =0; I < Num +1; i++) TenS[i] =0; One returnS; A } - - voidDestroy (disjset S) the { - Delete [] S; - } - + voidUnion (Disjset S, SetType root1, SetType root2) - { +S[ROOT2] =root1; A } at - SetType Find (disjset S, ElementType X) - { - if(S[x] <=0) - returnX; - Else in returnFind (S, s[x]); - } to + intMain () - { the intElementnum =8; *Disjset S =Initialize (Elementnum); $ Panax NotoginsengUnion (S,5,6); -Union (S,7,8); theUnion (S,5,7); + Acout << (Find (S),4) = = Find (S,5)) <<Endl; thecout << (Find (S),6) = = Find (S,8)) <<Endl; + - Destroy (S); $System"Pause"); $ return 0; -}
View Code
In order to avoid the depth of the tree, you can make the depth of the tree as a new root each time, so as to reduce the tree depth increase rate.
Then we need to remember the depth of the current root, and since we only take an array, we can let the value of the root be negative and represent the depth.
this way, the root node has a value of-1, which indicates a depth of-1.
For the above scenario, the Union (4,5) is executed. Follow the previous union operation to get the result:
Results after optimization
The array corresponding to the optimized result is as follows:
1 voidUnion (Disjset S, SetType root1, SetType root2)2 { 3 if(S[root2] <S[ROOT1])4S[ROOT1] =Root2; 5 Else 6 { 7 if(S[ROOT1] = =S[root2])8s[root1]--; 9S[ROOT2] =root1; Ten } One}
View Code
For deeper trees, the find operation is time-consuming and recursive to the root of the tree step-by-step.
Improved thinking: After executing a find, let all nodes in the path point directly to the root, without pointing to the father, so that the next time you find the root can be quickly found, save time.
Perform a Find (8) operation once. Since the root of the tree in element 8 is 5, the array becomes after the find is executed.
This way, when the next call to find (8), you can quickly find 8 corresponding root.
1 SetType Find (disjset S, ElementType X) 2 { 3 if0) 4 return X ; 5 Else 6 return S[X] = Find (S, s[x]); 7 }
View Code
Transferred from: http://blog.csdn.net/spch2008/article/details/9338943
Data structure and algorithm analysis (IV.)--disjoint set