并查集算法(Java)

目录

一、算法思想概述

二、代码(一):

三、代码(二)


一、算法思想概述

并查集算法可以认为主要是用来寻找相同性质的元素,讲这些元素放在一起,当然,这里的相同性质也是灵活变化的。有时候,我们需要对问题需要换一种角度来思考,比如在一群城市之间,如果我们要找那些城市是相连的,并把能够相互联通的两个城市放入一个集合当中,一个集合代表一个城市群,我们要寻找有多少个城市群,也就是要寻找有多少个集合。

并查集的主要步骤就是,一开始每个元素都有自己的集合,这个集合中只有自己这个元素。有一个find(i)方法,用来查找i所在集合的代表元素,表示该元素所在的集合。还有一个isSameSet(a,b)的方法,主要是用来判断a和b是否在同一个集合中,union(a,b),将a所在的集合与b所在的集合合并成一个集合,各种操作单词调用的均摊时间复杂度为O(1)。

二、代码(一):

find()方法在查找父亲节点的时候,是一直循环查找当前节点的父节点,直到,找到一个结点,该节点的父节点就是自己本身,此时说明已经找到了,即祖先节点。

isSameSet方法,就是调用find方法来判断两个节点是否属于同一个集合。

union方法,用来合并两个集合,同样是调用了find方法,将两个集合的祖先结点,将两者的祖先结点进行合并,这样,他们就属于一个集合之中了,并涉及了一个小挂大的操作来保证构成的集合树结构深度不会太大。

java 复制代码
package FunctionProm;

/**
 * 并查集算法 
 */
 public class Main2 {
    public static int MAXN=1000001;
    public static int[] father=new int[MAXN];//表示自己的父集合    
    public static int[] size=new int[MAXN];//表示自己集合大小    
    public static int[] stack=new int[MAXN];//表示查找沿途的结点,用于做扁平化    
    public static int n;
    //创建    
    public static void build(){
        for(int i=0;i<=n;i++){
            father[i]=i;
            size[i]=1;
        }
    }
    public static int find(int i){
        int size=0;
        while (i!=father[i]){
            stack[size++]=i;
            i=father[i];
        }
        while (size>0){
            father[stack[--size]]=i;
        }
        return i;
    }
    public static boolean isSameSet(int x,int y){
        return find(x)==find(y);
    }
    public static void union(int x,int y){
        int fx=find(x);
        int fy=find(y);
        if(fx!=fy){
            if(size[fx]>=size[fy]){
                size[fx]+=size[fy];
                father[fy]=fx;
            }else{
                size[fy]+=size[fx];
                father[fx]=fy;
            }
        }
    }
}

三、代码(二)

这段代码比上面的那个代码就要复杂,其中在find方法中,我们会采用一种扁平化的思想,也就是我们在找父节点的时候,直接将祖宗结点,即最顶部的节点赋给某个节点的父亲中,因此,在下一次查找父亲节点的时候,直接查找一次就可以查找到,查找速度比较快。

java 复制代码
package FunctionProm;

/**
 * 并查集算法(洛谷版本),用递归实现 
 */
 public class Main3 {
    public static int MAXN=1000001;
    public static int[] father=new int[MAXN];//表示自己的父集合    
    public static int n;
    //创建    
    public static void build(){
        for(int i=0;i<=n;i++){
            father[i]=i;
        }
    }
    public static int find(int i){//满足扁平化        
    if(i!=father[i]){
            father[i]=find(father[i]);
        }
        return father[i];
    }
    public static boolean isSameSet(int x,int y){
        return find(x)==find(y);
    }
    public static void union(int x,int y){
       father[find(x)]=find(y);
    }
}
相关推荐
lulu_gh_yu18 分钟前
数据结构之排序补充
c语言·开发语言·数据结构·c++·学习·算法·排序算法
~yY…s<#>2 小时前
【刷题17】最小栈、栈的压入弹出、逆波兰表达式
c语言·数据结构·c++·算法·leetcode
XuanRanDev3 小时前
【每日一题】LeetCode - 三数之和
数据结构·算法·leetcode·1024程序员节
代码猪猪傻瓜coding3 小时前
力扣1 两数之和
数据结构·算法·leetcode
南宫生4 小时前
贪心算法习题其三【力扣】【算法学习day.20】
java·数据结构·学习·算法·leetcode·贪心算法
weixin_432702265 小时前
代码随想录算法训练营第五十五天|图论理论基础
数据结构·python·算法·深度优先·图论
passer__jw7676 小时前
【LeetCode】【算法】283. 移动零
数据结构·算法·leetcode
爱吃生蚝的于勒7 小时前
深入学习指针(5)!!!!!!!!!!!!!!!
c语言·开发语言·数据结构·学习·计算机网络·算法
羊小猪~~7 小时前
数据结构C语言描述2(图文结合)--有头单链表,无头单链表(两种方法),链表反转、有序链表构建、排序等操作,考研可看
c语言·数据结构·c++·考研·算法·链表·visual studio
脉牛杂德7 小时前
多项式加法——C语言
数据结构·c++·算法