首页 > 其他 > 详细

DisjointSet并查集

时间:2020-08-06 15:00:15      阅读:75      评论:0      收藏:0      [点我收藏+]

1.1概述

并查集是一种树形的数据结构,用于处理不交集的合并(union)及查询(find)问题。并查集可用于查询网络中两个节点的状态, 这里的网络是一个抽象的概念, 不仅仅指互联网中的网络, 也可以是人际关系的网络、交通网络等。

1.2详解

并查集的重要思想在于,用集合中的一个元素代表集合。我曾看过一个有趣的比喻,把集合比喻成帮派,而代表元素则是帮主。接下来我们利用这个比喻,看看并查集是如何运作的。
首先每个人都各自为阵:
技术分享图片
然后根据情况对其中的集合进行合并:也就是指向一个集合的代表。
技术分享图片
上面步骤就是并查集的合并操作,另外一个比较重要的操作就是查询操作,判断两个元素是否是同一个集合。

1.3代码

  • 这里采用数组的形式实现并查集,其中值为-1代表该元素为集合代表,其他则代表该元素所处集合的代表坐标。
  • 这里实现的只是最简单的版本,其中元素只能为正整数(也就是数组的下标)。拓展版本可以借助map集合实现下标和元素的映射关系。
  • 其实还可以进行优化操作,这里的版本很明显最后生成的结构是一棵树,假如运气不好,所有节点都在上一个节点的同一侧,就退化成了链表形式了。所以可以增加一个rank数组来记录树的高度,合并的时候作为判断依据避免树退化成链表。也可以将所有节点都直接指向root节点,这样就是棵n叉树,只有两层。
package disjointset;

import java.util.Arrays;

/**
 * JavaTest
 *
 * @author : xgj
 * @description : 并查集简单实现
 * @date : 2020-08-05 20:43
 **/
public class DisjointSet {
    /**
     * 底层数组
     */
    private int[] parent;
    /**
     *并查集的元素个数
     */
    private int size;
    /**
     *功能描述 : 初始化,元素指向-1
     *
     * @author xgj
     * @date 2020/8/5
     */
    public DisjointSet(int size) {
        //初始化个数
        this.size = size;
        //初始化数组,每个并查集都指向自己
        parent = new int[size];
        Arrays.fill(parent,-1);
    }
    /**
     *功能描述 : 找到父节点
     *
     * @author xgj
     * @date 2020/8/5
     */
    private int find(int element) {
        if(element > size || element < 0){
            System.out.println("范围错误");
        }
        if(parent[element] == -1) {
            return element;
        }
        return find(parent[element]);
    }
    /**
     *功能描述 : 查询是否属于一组
     *
     * @author xgj
     * @date 2020/8/5
     * @param element1
     * @param element2
     * @return boolean
     */
    public boolean isConnected(int element1 ,int element2){
        int parent1 = find(element1);
        int parent2 = find(element2);
        return parent1 == parent2;
    }
    /**
     *功能描述 : 合并两个元素所在集合
     *
     * @author xgj
     * @date 2020/8/5
     * @param element1
     * @param element2
     * @return boolean
     */
    public boolean unionElements(int element1,int element2){
        int parent1 = find(element1);
        int parent2 = find(element2);
        if(parent1 == parent2) {
            return false;
        }
        parent[parent1] = parent2;
        return true;
    }
    /**
     *功能描述 : 输出并查集
     *
     * @author xgj
     * @date 2020/8/5
     * @param
     * @return void
     */
    public void printArr(){
        System.out.println(Arrays.toString(parent));
    }
}

DisjointSet并查集

原文:https://www.cnblogs.com/jiezao/p/13445823.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!