-
Notifications
You must be signed in to change notification settings - Fork 212
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
tianbin
committed
Nov 2, 2022
1 parent
20f702a
commit dd31564
Showing
6 changed files
with
188 additions
and
30 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
package data_struct; | ||
|
||
/** | ||
* Created by nibnait on 2022/11/02 | ||
*/ | ||
public class Node<T> { | ||
public T value; | ||
|
||
public Node(T v) { | ||
value = v; | ||
} | ||
|
||
public static <T> Node v(T v) { | ||
return new Node(v); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
package data_struct.ds3_并查集; | ||
|
||
/** | ||
* Created by nibnait on 2022/11/02 | ||
*/ | ||
public interface MyUnionFind<T> { | ||
|
||
/** | ||
* 找到 当前节点 的代表节点 | ||
*/ | ||
T findAncestor(T cur); | ||
|
||
/** | ||
* 是否在同一个集合内 | ||
*/ | ||
boolean isSameSet(T a, T b); | ||
|
||
/** | ||
* 把 a 节点,并入 b 节点所在集合中 | ||
*/ | ||
void union(T a, T b); | ||
|
||
/** | ||
* 当前一共有多少个集合 | ||
*/ | ||
int size(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,119 @@ | ||
package data_struct.ds3_并查集; | ||
|
||
import com.google.common.collect.Lists; | ||
import data_struct.Node; | ||
import org.apache.commons.collections4.CollectionUtils; | ||
import org.junit.Assert; | ||
import org.junit.Test; | ||
|
||
import java.util.HashMap; | ||
import java.util.List; | ||
import java.util.Map; | ||
import java.util.Stack; | ||
|
||
/** | ||
* Created by nibnait on 2022/11/02 | ||
*/ | ||
public class UnionFind { | ||
|
||
@Test | ||
public void testCase() { | ||
|
||
Node node1 = Node.v(1); | ||
Node node2 = Node.v(2); | ||
Node node3 = Node.v(3); | ||
Node node4 = Node.v(4); | ||
Node node5 = Node.v(5); | ||
|
||
UnionFindImpl unionFind = new UnionFindImpl(Lists.newArrayList(node1, node2, node3, node4, node5)); | ||
Assert.assertEquals(5, unionFind.size()); | ||
Assert.assertFalse(unionFind.isSameSet(node1, node2)); | ||
Assert.assertEquals(node1, unionFind.findAncestor(node1)); | ||
|
||
unionFind.union(node1, node2); | ||
Assert.assertTrue(unionFind.isSameSet(node1, node2)); | ||
Assert.assertEquals(4, unionFind.size()); | ||
Assert.assertEquals(node1, unionFind.findAncestor(node2)); | ||
|
||
unionFind.union(node3, node4); | ||
Assert.assertEquals(3, unionFind.size()); | ||
Assert.assertEquals(node3, unionFind.findAncestor(node4)); | ||
|
||
unionFind.union(node1, node5); | ||
Assert.assertEquals(2, unionFind.size()); | ||
|
||
unionFind.union(node2, node4); | ||
Assert.assertEquals(node1, unionFind.findAncestor(node4)); | ||
|
||
} | ||
|
||
public class UnionFindImpl implements MyUnionFind<Node> { | ||
|
||
// 存放节点对应的直系父亲节点 | ||
private Map<Node, Node> fathers; | ||
// 存放 祖先节点 对应的集合的大小。 | ||
private Map<Node, Integer> sizeMap; | ||
|
||
public UnionFindImpl(List<Node> nodes) { | ||
fathers = new HashMap<>(); | ||
sizeMap = new HashMap<>(); | ||
if (CollectionUtils.isEmpty(nodes)) { | ||
return; | ||
} | ||
for (Node node : nodes) { | ||
fathers.put(node, node); | ||
sizeMap.put(node, 1); | ||
} | ||
} | ||
|
||
/** | ||
* 优化点1:为了每次往上找的链 都能更短一点。 | ||
* 可以找完之后把这一串节点全部打平,直接挂在 ancestor 下面 | ||
*/ | ||
@Override | ||
public Node findAncestor(Node cur) { | ||
Stack<Node> stack = new Stack<>(); | ||
while (cur != fathers.get(cur)) { | ||
stack.push(cur); | ||
cur = fathers.get(cur); | ||
} | ||
|
||
while (!stack.isEmpty()) { | ||
Node node = stack.pop(); | ||
fathers.put(node, cur); | ||
} | ||
return cur; | ||
} | ||
|
||
@Override | ||
public boolean isSameSet(Node a, Node b) { | ||
return findAncestor(a) == findAncestor(b); | ||
} | ||
|
||
/** | ||
* 优化点2:为了链的长度涨的慢一点。 | ||
* 可以小集合的头节点 往大集合上挂。 | ||
*/ | ||
@Override | ||
public void union(Node a, Node b) { | ||
Node aHead = findAncestor(a); | ||
Node bHead = findAncestor(b); | ||
if (aHead == bHead) { | ||
return; | ||
} | ||
|
||
Integer aSize = sizeMap.get(aHead); | ||
Integer bSize = sizeMap.get(bHead); | ||
Node big = aSize >= bSize ? aHead : bHead; | ||
Node small = big == aHead ? bHead : aHead; | ||
fathers.put(small, big); | ||
sizeMap.put(big, aSize + bSize); | ||
sizeMap.remove(small); | ||
} | ||
|
||
@Override | ||
public int size() { | ||
return sizeMap.size(); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
## 并查集 | ||
[并查集 数据结构](../../../java/data_struct/ds3_并查集) | ||
|