I started playing and querying the set two days ago. I didn't know it at the time, but now I only know this. I have been asking du Niang for a long time. At most, I was told to write two functions, I think there should be many people who want to know what I want but cannot express clearly, So Baidu has not found the answer for a long time. So, how can I obtain and query the set and share it with what I want to know at the time ~~
First, I want to check whether the set has the same container as the stack and queue. That is to say, when the header file is added, a variable can be defined, in addition, the functions of the stack and the stack are in the header file instead of writing them by yourself. The answer is: If so, it would be too easy to query the set.
In general, the query set contains the find and Union super-heavyweight functions. Of course, I also want to know if this name is a special term. If it is wrong, this function is written by myself, set the name by yourself. Here we will talk about their functions.
The find function is used to find the ancestor of the family in which the member belongs (no reading is done, so the data in the root is called the ancestor. I don't know if the data in the book is like this), but there are two solutions.
Find Statement 1,
Int find_set (int x) // "trace back", and direct its child nodes to the ancestor.
{
If (X! = Father [x])
{
Father [x] = find_set (father [x]); // points to the ancestor
} Return father [X]; // returns the ancestor
} \ Uses a rank array to store the depth lower bound of the set. path compression is performed during the search operation to accelerate subsequent search operations.
This will point all the fathers found in the search process to the final ancestor. ** this is a super important point. I accidentally saw a blog suddenly understood, I should have understood this sentence better, hey
Find_set (int x) // you can write your own questions in this way, which is cost-effective and cost-effective. You know...
{
Return x = Father [x]? X: Father [x] = find_set (father [x]);
}
Find Statement 2,
Int find_set (int x)
{
While (X! = Father [x])
{
X = Father [X]; // only finds the ancestor, but does not change the Member's direction.
} Return father [x];
}
This is almost the same as the one above, but there will be no changes to the Members, but this is indeed a big advantage over the one above. Many people may not notice that it uses a loop, the first one is recursion, and the previous one may overflow the stack segment. I don't understand the meaning of the stack segment. I only see one sentence. Every time a function is called, what frame is added, no matter what it is, calling a function will increase the space. Speaking of this, we can understand all this. recursion is a function loop. Therefore, hangdian has a question that many people use re (stack_overflow ), stack explosion is not to say that you have written a mistake. It is because the data has caused too many times of calling the find function (do not ask me or study it). When the recursive one is widely recognized, so everyone uses it. When you change it to a loop, you will know that this solution is really cute !!
Then there is union, which is used to merge two families. There are also simple versions and slightly complex versions, but it is so simple that the following is the simple version.
Void UN (int x, int y)
{
If (find_set (x )! = Find_set (y) // when the ancestor of X is not equal to the ancestor of Y, the ancestor of Y is directed to the ancestor of X.
Father [find_set (y)] = find_set (X );
}
This is what I wrote below, because we don't need to call more find functions (the order of X and Y can be disrupted)
Void UN (int x, int y)
{
X = find_set (x), Y = find_set (y );
If (X! = Y) Father [y] = X;
}
In a complex version, one more judgment can be made to determine which family is "swallowed up"
This is almost the case. I come here anyway. If you still don't understand it, let the beauty next to you go away first, and then you can read it again, after all, beauty is more attractive ^