最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java數(shù)據(jù)結(jié)構(gòu)之并查集的實(shí)現(xiàn)

 更新時(shí)間:2022年01月23日 15:51:04   作者:chaojilaji  
并查集是一種用來(lái)管理元素分組情況的數(shù)據(jù)結(jié)構(gòu)。并查集可以高效地進(jìn)行如下操作。本文將通過(guò)Java實(shí)現(xiàn)并查集,感興趣的小伙伴可以了解一下

并查集就是將原本不在一個(gè)集合里面的內(nèi)容合并到一個(gè)集合中。

在實(shí)際的場(chǎng)景中用處不多。

除了出現(xiàn)在你需要同時(shí)去幾個(gè)集合里面查詢,避免出現(xiàn)查詢很多次,從而放在一起查詢的情況。

下面簡(jiǎn)單實(shí)現(xiàn)一個(gè)例子,我們來(lái)舉例說(shuō)明一下什么是并查集,以及究竟并查集解決了什么問(wèn)題。

代碼解析

package com.chaojilaji.book.andcheck;

public class AndCheckSet {


    public static Integer getFather(int[] father, int u) {
        if (father[u] != u) {
            father[u] = getFather(father, father[u]);
        }
        return father[u];
    }

    public static void join(int[] father,int x, int y) {
        int fx = getFather(father,x);
        int fy = getFather(father,y);
        if (fx != fy){
            father[fx] = fy;
        }
    }

    public static void main(String[] args) {
        int n = 10;
        int[] a = new int[n];
        for (int i = 0;i<n;i++){
            a[i] = i; // 初始化定義一百個(gè)集合
        }
        for (int i=0;i<n;i++){
            System.out.println(i+" "+getFather(a, i)); // 對(duì)于每個(gè)集合,父節(jié)點(diǎn)都是自己
        }
    }
}

首先,我們定義了兩個(gè)函數(shù),分別為getFather和join,分別表示獲取u所在集合的根以及合并兩個(gè)集合。

先來(lái)看看getFather方法

public static Integer getFather(int[] father, int u) {
    if (father[u] != u) {
        father[u] = getFather(father, father[u]);
    }
    return father[u];
}

是找出值u所在集合的根節(jié)點(diǎn)是多少。一般來(lái)說(shuō),father[u]如果等于u本身,那么說(shuō)明u所在節(jié)點(diǎn)就是根節(jié)點(diǎn),而這個(gè)算法是直到相等才退出,也就是說(shuō),對(duì)于從u到根節(jié)點(diǎn)的每個(gè)節(jié)點(diǎn)的father都被直接置為根節(jié)點(diǎn),同時(shí)返回了當(dāng)前節(jié)點(diǎn)的根節(jié)點(diǎn)。

然后來(lái)看看join方法

public static void join(int[] father,int x, int y) {
    int fx = getFather(father,x);
    int fy = getFather(father,y);
    if (fx != fy){
        father[fx] = fy;
    }
}

分別找出x和y兩個(gè)節(jié)點(diǎn)所在集合的根節(jié)點(diǎn),如果根節(jié)點(diǎn)不一樣,則將其中一個(gè)節(jié)點(diǎn)的father節(jié)點(diǎn)置為另一個(gè)節(jié)點(diǎn)即可,這樣就合并成了一個(gè)集合。

代碼應(yīng)用

public static void main(String[] args) {
    int n = 10;
    int[] a = new int[n];
    for (int i = 0;i<n;i++){
        a[i] = i; // 初始化定義n個(gè)集合
    }
    for (int i=0;i<n;i++){
        System.out.println(i+" "+getFather(a, i)); // 對(duì)于每個(gè)集合,父節(jié)點(diǎn)都是自己
    }
    System.out.println("-------------------------");
    join(a,0,1); // 合并 0 和 1
    for (int i=0;i<n;i++){
        System.out.println(i+" "+getFather(a, i));
    }
    // 由于合并了0和1,所以集合變成了9個(gè),節(jié)點(diǎn)0和節(jié)點(diǎn)1的根都是節(jié)點(diǎn)1
    System.out.println("-------------------------");
    join(a,2,3); // 合并 2 和 3
    for (int i=0;i<n;i++){
        System.out.println(i+" "+getFather(a, i));
    }
    // 由于合并了2和3,所以集合變成8個(gè),節(jié)點(diǎn)2和節(jié)點(diǎn)3的根都是節(jié)點(diǎn)3
    System.out.println("-------------------------");
    join(a,1,3); // 合并 1 和 3
    for (int i=0;i<n;i++){
        System.out.println(i+" "+getFather(a, i));
    }
    // 由于合并了1和3,所以集合變成7個(gè),節(jié)點(diǎn)0,1,2,3的根都是節(jié)點(diǎn)3
}

首先,我們定義了n個(gè)集合,這n個(gè)集合的值是0~n-1,然后此時(shí)他們的父節(jié)點(diǎn)均等于他們本身,所以這就是n個(gè)獨(dú)立的集合,結(jié)果如下

0的父節(jié)點(diǎn)為 0 1的父節(jié)點(diǎn)為 1 2的父節(jié)點(diǎn)為 2 3的父節(jié)點(diǎn)為 3 4的父節(jié)點(diǎn)為 4 5的父節(jié)點(diǎn)為 5 6的父節(jié)點(diǎn)為 6 7的父節(jié)點(diǎn)為 7 8的父節(jié)點(diǎn)為 8 9的父節(jié)點(diǎn)為 9

然后調(diào)用 join(a,0,1)合并0集合和1集合,再輸出節(jié)點(diǎn)父集合情況為

0的父節(jié)點(diǎn)為 1 1的父節(jié)點(diǎn)為 1 2的父節(jié)點(diǎn)為 2 3的父節(jié)點(diǎn)為 3 4的父節(jié)點(diǎn)為 4 5的父節(jié)點(diǎn)為 5 6的父節(jié)點(diǎn)為 6 7的父節(jié)點(diǎn)為 7 8的父節(jié)點(diǎn)為 8 9的父節(jié)點(diǎn)為 9

可以看見(jiàn),由于合并了0和1,所以集合變成了9個(gè),節(jié)點(diǎn)0和節(jié)點(diǎn)1的根都是節(jié)點(diǎn)1。
然后調(diào)用 join(a,2,3) 合并2集合和3集合,輸出節(jié)點(diǎn)父集合情況為

0的父節(jié)點(diǎn)為 1 1的父節(jié)點(diǎn)為 1 2的父節(jié)點(diǎn)為 3 3的父節(jié)點(diǎn)為 3 4的父節(jié)點(diǎn)為 4 5的父節(jié)點(diǎn)為 5 6的父節(jié)點(diǎn)為 6 7的父節(jié)點(diǎn)為 7 8的父節(jié)點(diǎn)為 8 9的父節(jié)點(diǎn)為 9

可以看見(jiàn),由于合并了2和3,所以集合變成8個(gè),節(jié)點(diǎn)2和節(jié)點(diǎn)3的根都是節(jié)點(diǎn)3。
最后,我們?cè)僬{(diào)用join(a,1,3) 合并1集合和3集合,輸出節(jié)點(diǎn)父集合情況為

0的父節(jié)點(diǎn)為 3 1的父節(jié)點(diǎn)為 3 2的父節(jié)點(diǎn)為 3 3的父節(jié)點(diǎn)為 3 4的父節(jié)點(diǎn)為 4 5的父節(jié)點(diǎn)為 5 6的父節(jié)點(diǎn)為 6 7的父節(jié)點(diǎn)為 7 8的父節(jié)點(diǎn)為 8 9的父節(jié)點(diǎn)為 9

可以看出來(lái),由于合并了1和3,所以集合變成7個(gè),節(jié)點(diǎn)0,1,2,3的根都是節(jié)點(diǎn)3。

實(shí)際應(yīng)用

代碼的層面來(lái)講,并查集很好實(shí)現(xiàn)。但是我們卻也可以發(fā)現(xiàn),其應(yīng)用場(chǎng)景似乎非常局限。
首先,我們需要定義出一個(gè)father[x] = x的數(shù)組,然后我們?cè)偃ズ喜?。似乎很難想到應(yīng)用場(chǎng)景。

那么我們可以想象一個(gè)場(chǎng)景,現(xiàn)在有個(gè)網(wǎng)絡(luò)拓?fù)鋱D,里面有n和網(wǎng)絡(luò)設(shè)施設(shè)備,然后又給了你這n個(gè)設(shè)施設(shè)備之間的連接關(guān)系,問(wèn)你一共有多少個(gè)局部聯(lián)通網(wǎng)。
對(duì)于這個(gè)問(wèn)題,我們就可以首先定義每個(gè)設(shè)備自己跟自己相連,然后每出現(xiàn)一條邊,就對(duì)這兩個(gè)設(shè)備采取join操作。最終我們?cè)诒闅v完所有的節(jié)點(diǎn),得到多少個(gè)不同的father,即表示有多少個(gè)不同的局部聯(lián)通網(wǎng)。

這樣的問(wèn)題還可以延伸到我們的人際交友圈,首先每個(gè)人都是單獨(dú)的集合,在不斷認(rèn)識(shí)人的過(guò)程中,產(chǎn)生連通性。最終讓你確認(rèn)一共有多少個(gè)不互通的人際圈。

所以你會(huì)發(fā)現(xiàn),這本質(zhì)上就是求圖論中連通塊的個(gè)數(shù)。

到此這篇關(guān)于Java數(shù)據(jù)結(jié)構(gòu)之并查集的實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)Java并查集內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java動(dòng)態(tài)顯示當(dāng)前日期和時(shí)間

    Java動(dòng)態(tài)顯示當(dāng)前日期和時(shí)間

    這篇文章主要為大家詳細(xì)介紹了Java動(dòng)態(tài)顯示當(dāng)前日期和時(shí)間,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-12-12
  • 如何解決Springboot?Dao注入失敗的問(wèn)題

    如何解決Springboot?Dao注入失敗的問(wèn)題

    這篇文章主要介紹了如何解決Spring?boot?Dao注入失敗的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-05-05
  • java構(gòu)造函數(shù)示例(構(gòu)造方法)

    java構(gòu)造函數(shù)示例(構(gòu)造方法)

    這篇文章主要介紹了java構(gòu)造函數(shù)示例(構(gòu)造方法),需要的朋友可以參考下
    2014-03-03
  • Java異常javax.net.ssl.SSLHandshakeException: SSL的解決方法

    Java異常javax.net.ssl.SSLHandshakeException: SSL的解決方法

    在Java開(kāi)發(fā)過(guò)程中,SSL(Secure Sockets Layer)握手異常是一個(gè)常見(jiàn)的網(wǎng)絡(luò)通信錯(cuò)誤,特別是在使用HTTPS協(xié)議進(jìn)行安全通信時(shí),本文將詳細(xì)分析javax.net.ssl.SSLHandshakeException: SSL這一異常的背景、可能的原因,并通過(guò)代碼示例幫助您理解和解決這一問(wèn)題
    2024-12-12
  • 深度理解Java訪問(wèn)修飾符

    深度理解Java訪問(wèn)修飾符

    今天帶大家學(xué)習(xí)的是Java的相關(guān)知識(shí),文章圍繞著Java訪問(wèn)修飾符展開(kāi),有非常詳細(xì)的介紹及代碼示例,需要的朋友可以參考下
    2021-06-06
  • Java 由淺入深帶你掌握?qǐng)D的遍歷

    Java 由淺入深帶你掌握?qǐng)D的遍歷

    圖的遍歷是指,從給定圖中任意指定的頂點(diǎn)(稱為初始點(diǎn))出發(fā),按照某種搜索方法沿著圖的邊訪問(wèn)圖中的所有頂點(diǎn),使每個(gè)頂點(diǎn)僅被訪問(wèn)一次,這個(gè)過(guò)程稱為圖的遍歷。遍歷過(guò)程中得到的頂點(diǎn)序列稱為圖遍歷序列
    2022-03-03
  • SpringMVC返回的ResponseEntity出現(xiàn)亂碼及解決

    SpringMVC返回的ResponseEntity出現(xiàn)亂碼及解決

    這篇文章主要介紹了SpringMVC返回的ResponseEntity出現(xiàn)亂碼及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-02-02
  • Java annotation元注解原理實(shí)例解析

    Java annotation元注解原理實(shí)例解析

    這篇文章主要介紹了Java annotation元注解原理實(shí)例解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-03-03
  • Java并發(fā)編程 interrupt()方法示例詳解

    Java并發(fā)編程 interrupt()方法示例詳解

    interrrupt()方法可以用來(lái)打斷正在運(yùn)行的線程,也可以打斷sleep()、wait()、join()情況下的線程,但是這些情況下被打斷線程的打斷標(biāo)記不同,這篇文章主要介紹了Java并發(fā)編程 interrupt()方法示例詳解,需要的朋友可以參考下
    2023-06-06
  • Java Druid連接池與Apache的DBUtils使用教程

    Java Druid連接池與Apache的DBUtils使用教程

    這篇文章主要介紹了Java Druid連接池與Apache的DBUtils使用方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2022-12-12

最新評(píng)論

枣强县| 买车| 文登市| 新沂市| 赤水市| 玉门市| 长武县| 霍州市| 武邑县| 华阴市| 红河县| 牙克石市| 定州市| 山丹县| 霍城县| 巴塘县| 古丈县| 东平县| 定襄县| 普宁市| 修水县| 武清区| 栾川县| 孟村| 长顺县| 静安区| 清水县| 浦城县| 嘉义市| 蓬安县| 东辽县| 利川市| 商洛市| 龙泉市| 渝北区| 阿拉善右旗| 汝城县| 库尔勒市| 南华县| 乌鲁木齐县| 九江市|