算法#08--深入详解并查集union-find算法

深入详解并查集union-find算法

动态连通性

1. 问题描述

输入一系列整数对,其中每个整数都表示一个某种类型的对象,一对整数pq可以理解为“p和q是相连的”。

相连是一种对等关系,它需要具有以下性质:

  • 自反性:p和p是相连的。

  • 对称性:如果p和q是相连的,那么q和p也是相连的。

  • 传递性:如果p和q是相连的且q和r也是相连的,那么p和r也是相连的。

假设我们输入了一组整数对,即下图中的(4, 3) (3, 8)等等,每对整数代表这两个points/sites是连通的。那么随着数据的不断输入,整个图的连通性也会发生变化,从上图中可以很清晰的发现这一点。同时,对于已经处于连通状态的points/sites,直接忽略,比如上图中的(8, 9)。

2. 应用场景

  • 网络:整数表示的可能是一个大型计算机网络中的计算机,而整数对表示网络中的无数个连接。这个程序能够判断我们是否需要在p和q之间架一条新的连接才能进行通信。

  • 变量名等同性(类似于指针的概念):
    在程序中,可以声明多个引用来指向同一对象,这个时候就可以通过为程序中声明的引用和实际对象建立动态连通图来判断哪些引用实际上是指向同一对象。

  • 数学集合:在更高的抽象层次上,可以将输入的所有整数看做属于不同的数学集合。在处理一个整数对pq时,我们是在判断它们是否属于同一个集合。如果不是,我们会归并,最终所有整数属于同一集合。

3. 数学建模

在对问题进行建模的时候,我们应该尽量想清楚需要解决的问题是什么。因为模型中选择的数据结构和算法显然会根据问题的不同而不同,就动态连通性这个场景而言,我们需要解决的问题可能是:

  • 给出两个节点,判断它们是否连通,如果连通,不需要给出具体的路径

  • 给出两个节点,判断它们是否连通,如果连通,需要给出具体的路径

就上面两种问题而言,虽然只有是否能够给出具体路径的区别,但是这个区别导致了选择算法的不同,本文主要介绍的是第一种情况,即不需要给出具体路径的Union-Find算法,而第二种情况可以使用基于DFS的算法。

quick-find算法

1. API

注意:其中使用整数来表示节点,如果需要使用其他的数据类型表示节点,比如使用字符串,那么可以用哈希表来进行映射,即将String映射成这里需要的Integer类型。

2. 原理

举个例子,比如输入的整数对是(5, 9),那么首先通过find方法发现它们的组号并不相同,然后在union的时候通过一次遍历,将组号1都改成8。当然,由8改成1也是可以的,保证操作时都使用一种规则就行。

3. 代码

import java.util.Scanner;

public class UF {
    private int[] id; // 分量id(以触点作为索引)  

    private int count; // 分量数量  

    public UF(int N)  
    {  
        // 初始化分量id数组.  
        count = N;  
        id = new int[N];  
        for (int i = 0; i < N; i++)  
            id[i] = i;  
    }  

    public int count()  { 
        return count; 
    }  
    public boolean connected(int p, int q)  { 
        
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值