Algorithm topic
-
Collections
-
Union
Title: computer 10, numbered as follows: {} 1,2,3,4,5,6,7,8,9,10, following known among computer to complete the connection,
1 sum 2,2 sum 4,3 sum 5,4 sum 7,5 sum 8,6 sum 9,6 sum 10;
1 and 2, 2 and 4, such connection, also considered 1 and 4 connected,
Seeking between 2 and 7, is connected between 5 and 9?
c-check to check,
I-INPUT Input
Thought:
-
-
10 as these computer 10 sets, {1}, {2}, {3}, {4} ... {9}, {10}
-
Who and who is connected, then that is who and who were union;
-
X and y are connected to whether the query is to see x, y with if sets;
consider:
- How to represent the set; consider the idea of the tree, which will help find and union
- How tree using data types? List or array constructed? Considering the need to find, it is represented by a tree with a lookup array, while the subject, given the length of the array is not required to expand the length of the array. very suitable;
- Array, a custom node object, the object containing data (PC number), parent (index of parent node, -1 indicates that the node is a root node)
- And calculating, change the value of its node object in the array to complete the subject of the request; specific code as follows
public class ComputerConnect {
private Node[] computers;
public ComputerConnect(int[] pcs) {
this.computers = new Node[pcs.length];
for (int i = 0; i < pcs.length; i++) {
computers[i]=new Node(pcs[i],-1);
}
}
class Node{
int data;
int parent;
public Node() {
}
public Node(int data, int parent) {
this.data = data;
this.parent = parent;
}
}
public int find(int pcNum){
int i;
// 寻找该computers数组内的data是否有该pc,若有则i为其index;
for (i = 0; i < computers.length && computers[i].data== pcNum; i++) ;
//若满足没有在数组中找到该pc的编号,则返回-1;
if (i>=computers.length) return -1;
//找到其根结点;
for (;computers[i].parent>=0;i=computers[i].parent);
//返回其根结点的索引
return i;
}
public void union(int pcNum1, int pcNum2){
int root1 = find(pcNum1);
int root2 = find(pcNum1);
if (root1!=root2) computers[root2].parent = root1;
}
}
optimization
Forget improvement point of the return code itself above;
carried out
union(2,1)
union(3,1)
union(4,1)
After the union (5,1)
tree will become increasingly high, slow down the search efficiency;
Improved point:
The union may continue to result in too high tree, leading to find too slow, so the trees can be and to the trees, usher in a new problem, how to distinguish the size of the tree?
Change the values of the parent, such as -1 which indicates a child node represents a total of 6 -6 subnodes;
Subsequently modified method may be union;
By rank merge
This method is called by merging rank, according to the height or size, merge together,
At the same time this problem, a digital computer numbering type, designed to be used as an index, the data does not require Node domain, or decoding algorithm design, in terms of index type can find a simplified process
for (i = 0; i < computers.length && computers[i].data== pcNum; i++) ;
This section of the circulation amount;
Path compression
The core idea: find the code modification, when looking for a node, the node promoted to the position of the second level in the tree; icon:
public int find(int pcNum){
int i;
for (i = 0; i < computers.length && computers[i].data== pcNum; i++) ;
if (i>=computers.length) return -1;
for (;computers[i].parent>=0;i=computers[i].parent);
computers[temp].perent = i;
return i;
}