1、集合
主要运算:两个集合的交,并,补,差,判定一个元素是否属于一个集合
2、并查集:主要就2个运算
1.集合之间合并
2.查看一个元素属于哪个结合
存储:
用树的结构存储一个集合,但不是采用二叉树,采用子节点指向父节点,只能通过子节点找父节点(双亲表示法:每个节点指针指向父亲)
主要运算:两个集合的交,并,补,差,判定一个元素是否属于一个集合
2、并查集:主要就2个运算
1.集合之间合并
2.查看一个元素属于哪个结合
存储:
用树的结构存储一个集合,但不是采用二叉树,采用子节点指向父节点,只能通过子节点找父节点(双亲表示法:每个节点指针指向父亲)
二维数组,第一维存数据,第二维存数据的父节点的索引,如果没有父节点就存-1;
import java.util.Arrays;
public class BingChaSet {
// 二维数组存并查集最主要的是要搞清楚数组的存储结构data[0][i]和data[1][i]和i各表示什么
// 查元素属于那个集合,集合用父节点表示
public static int find(int[][] data, int des) {
// 记录位置
int pos = 0;
// 寻找des的位置,从数组的0开始找,注意二维数组也是从0开始索引的
for (pos = 0; pos < data[0].length && data[0][pos] != des; pos++)
;
// 如果位置大于等于数据最大索引,没找到
if (pos >= data[0].length)
return -1;
// 找到了des的位置,开始找父节点,如果des的父节点不为-1;找他父节点的父节点
for (; data[1][pos] >= 0; pos = data[1][pos])
;
// 返回集合的根元素
return data[0][pos];
}
public static void union(int[][] data, int des1, int des2) {
// des1的根节点
int root1 = -1;
// des2的根节点
int root2 = -1;
// 找到root1和root2
root1 = find(data, des1);
System.out.println(root1);
root2 = find(data, des2);
// 如果root1不等于root2说明不在一个集合里,
System.out.println(root2);
if (root1 != root2)
// 将2个集合合并,要注意,这里还需要知道root1和root2的索引位置,因为数据的原因,这个索引位置好找
// 如果不是1-10这样的数据存储,还需要写一个方法用来寻找根节点的索引位置
data[1][root2 - 1] =root1 - 1;//root1-1是root1的索引位置
}
public static void main(String[] args) {
// 数据,二维数组存储,第一维存数据,第二维存父节点的索引
int[][] data = {
{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 },
{ -1, 0, -1, 0, 2, -1, 0, 2, 5, 8 } };
// int i =1;
// int i =2;
// int i =3;
// int i =4;
// int i =5;
// int i =6;
// int i =7;
// int i =8;
// int i =9;
// int i = 10;
// int i =11;
// System.out.println(find(data, i));
union(data,9,5);
System.out.println(Arrays.deepToString(data));
}
}