/**
* 快速查找法
* 网络连通性问题使用数组的索引和其对应的数值是否相同来解决
* 若两个元素之间是相互连通的那么,它对应的索引对应的值是一样的
*
*/
public class QuickFindUF{
private int[] id;
//初始化独立的单元
//时间复杂度:N
public QuickFindUF(int N){
id = new int[N];
for (int i = 0;i < N ; i++) {
id[i]=i;
}
}
//判断两个元素是否连通
//时间复杂度:1
public boolean connected(int p,int q){
return id[p] == id[q];
}
//找到第一个与id数组相等的id项,将它设置为第二个id对应的id项
//使得两个元素之间进行连通
//时间复杂度:N
public void union(int p,int q){
int pid = id[p];
int qid = id[q];
for (int i = 0; i<id.length; i++) {
if (id[i]==pid) id[i] = qid;
}
}
}
/**
* 无权快速合并算法
* 网络连通性问题
* 使用树形结构进行合并
* 将数组中的每一项都包含在树的父节点中
*
*/
public class QuickUnion{
private int[] id;
//初始化独立的单元
//时间复杂度:N
public QuickFindUF(int N){
id = new int[N];
for (int i = 0;i < N ; i++) {
id[i]=i;
}
}
//查找i对应的根节点函数,返回对应的根节点
private int root(int i){
while (i != id[i]) i = id[i];
return i;
}
//判断两个元素之间是否连通,即判断两个元素是否有相同的根节点
//最坏时间复杂度:N
public boolean connected(int p,int q){
return root(p) == root(q);
}
//合并两个元素,使得他们之间进行连通,将第一个元素p作为子节点连接
//在第二个元素q中找到根节点,即设置p索引对应的值为q的根节点
//最坏时间复杂度:N
public void union(int p, int q){
int i = root(p);
int j = root(q);
if (i == j) return;
id[i]=j;
}
}
/**
* 带权快速合并算法
* 网络连通性问题
* 使用树形结构进行合并,合理将小树放在大树的下方降低树的高度
* 将数组中的每一项都包含在树的父节点中
* 时间复杂度:O(log2n)
*/
public class QuickUnionWeight{
private int[] id;
private int[] size;
//初始化独立的单元
//时间复杂度:N
public QuickFindUF(int N){
id = new int[N];
for (int i = 0;i < N ; i++) id[i]=i;
for (int i = 0;i < N ; i++) size[i]=1;
}
//查找i对应的根节点函数,返回对应的根节点
private int root(int i){
while (i != id[i]) i = id[i];
return i;
}
//判断两个元素之间是否连通,即判断两个元素是否有相同的根节点
//时间复杂度:lgN
public boolean connected(int p,int q){
return root(p) == root(q);
}
//合并两个元素,使得他们之间进行连通,将第一个元素p作为子节点连接
//在第二个元素q中找到根节点,即设置p索引对应的值为q的根节点
//时间复杂度:lgN
public void union(int p, int q){
int i = root(p);
int j = root(q);
if(i==j) return;
if(size[i] < size[j]){
id[i] = j;
size[j] += size[i];
}else{
id[j]=i;
size[i] += size[j];
}
}
}
/**
* 带压缩路径带权快速合并算法
* 网络连通性问题
* 使用树形结构进行合并,合理将小树放在大树的下方降低树的高度
* 将数组中的每一项都包含在树的父节点中
* 时间复杂度:O(log2n)
*/
public class QuickUnionWeight{
private int[] id;
private int[] size;
//初始化独立的单元
//时间复杂度:N
public QuickFindUF(int N){
id = new int[N];
for (int i = 0;i < N ; i++) id[i]=i;
for (int i = 0;i < N ; i++) size[i]=1;
}
//查找i对应的根节点函数,返回对应的根节点
private int root(int i){
while (i != id[i]){
id[i] = id[id[i]];//加入带压缩路径
i = id[i];
}
return i;
}
//判断两个元素之间是否连通,即判断两个元素是否有相同的根节点
//时间复杂度:lgN
public boolean connected(int p,int q){
return root(p) == root(q);
}
//合并两个元素,使得他们之间进行连通,将第一个元素p作为子节点连接
//在第二个元素q中找到根节点,即设置p索引对应的值为q的根节点
//时间复杂度:lgN
public void union(int p, int q){
int i = root(p);
int j = root(q);
if(i==j) return;
if(size[i] < size[j]){
id[i] = j;
size[j] += size[i];
}else{
id[j]=i;
size[i] += size[j];
}
}
}复制代码
连通性问题的算法优化(Java版本)
最新推荐文章于 2023-04-04 21:11:20 发布