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

Java實(shí)現(xiàn)克魯斯卡爾算法的示例代碼

 更新時(shí)間:2023年04月14日 11:15:56   作者:周小末天天開心  
克魯斯卡爾算法是一種用于求解最小生成樹問題的貪心算法。這篇文章主要為大家詳細(xì)介紹了Java實(shí)現(xiàn)克魯斯卡爾算法的方法,需要的可以參考一下

克魯斯卡爾算法

克魯斯卡爾算法是一種用于求解最小生成樹問題的貪心算法。最小生成樹是一個(gè)連通無(wú)向圖中生成樹中邊權(quán)值和最小的生成樹。克魯斯卡爾算法按邊權(quán)值從小到大的順序依次選擇邊,當(dāng)所選的邊不會(huì)形成環(huán)時(shí),將其加入到生成樹中。具體實(shí)現(xiàn)過程如下:

  • 將所有邊按照邊權(quán)值從小到大排序。
  • 依次選擇邊,如果選擇的邊的兩個(gè)端點(diǎn)不在同一個(gè)連通分量中,則將這條邊加入到最小生成樹中,并將兩個(gè)端點(diǎn)合并為同一個(gè)連通分量。
  • 直到最小生成樹中包含了圖中的所有頂點(diǎn)為止。

算法的優(yōu)點(diǎn)在于只需要關(guān)注邊的權(quán)值,而與頂點(diǎn)的度數(shù)無(wú)關(guān),因此在稠密圖中也能表現(xiàn)出較好的性能。同時(shí),克魯斯卡爾算法還具有較好的可擴(kuò)展性,可以很方便地處理帶權(quán)圖中的最小生成森林問題。

執(zhí)行流程

  • 將所有的邊按照權(quán)值從小到大排序;
  • 依次遍歷每條邊,如果這條邊連接的兩個(gè)節(jié)點(diǎn)不在同一個(gè)連通分量中,則將這條邊加入生成樹,并將這兩個(gè)節(jié)點(diǎn)合并為一個(gè)連通分量;
  • 重復(fù)步驟 2 直到所有的節(jié)點(diǎn)都在同一個(gè)連通分量中,此時(shí)生成的樹即為最小生成樹。

在實(shí)現(xiàn)過程中,通常使用并查集來維護(hù)連通性,以提高效率。

代碼實(shí)現(xiàn)

import java.util.*;

public class KruskalAlgorithm {
    
    // 定義邊的數(shù)據(jù)結(jié)構(gòu)
    class Edge implements Comparable<Edge> {
        int src, dest, weight;
 
        public int compareTo(Edge edge) {
            return this.weight - edge.weight;
        }
    }
    
    // 并查集數(shù)據(jù)結(jié)構(gòu)
    class Subset {
        int parent, rank;
    }
 
    int V, E; // V是頂點(diǎn)數(shù),E是邊數(shù)
    Edge edge[]; // 存儲(chǔ)邊的數(shù)組
 
    // 構(gòu)造函數(shù),初始化邊和頂點(diǎn)數(shù)
    KruskalAlgorithm(int v, int e) {
        V = v;
        E = e;
        edge = new Edge[E];
        for (int i = 0; i < e; ++i)
            edge[i] = new Edge();
    }
 
    // 查找父節(jié)點(diǎn)
    int find(Subset subsets[], int i) {
        if (subsets[i].parent != i)
            subsets[i].parent = find(subsets, subsets[i].parent);
        return subsets[i].parent;
    }
 
    // 合并兩個(gè)子集
    void union(Subset subsets[], int x, int y) {
        int xroot = find(subsets, x);
        int yroot = find(subsets, y);
 
        if (subsets[xroot].rank < subsets[yroot].rank)
            subsets[xroot].parent = yroot;
        else if (subsets[xroot].rank > subsets[yroot].rank)
            subsets[yroot].parent = xroot;
        else {
            subsets[yroot].parent = xroot;
            subsets[xroot].rank++;
        }
    }
 
    // 執(zhí)行克魯斯卡爾算法
    void kruskal() {
        Edge result[] = new Edge[V]; // 存儲(chǔ)結(jié)果的數(shù)組
        int e = 0; // 表示result數(shù)組中的下標(biāo)
 
        // 將邊按照權(quán)重從小到大排序
        Arrays.sort(edge);
 
        // 創(chuàng)建V個(gè)子集
        Subset subsets[] = new Subset[V];
        for (int i = 0; i < V; ++i)
            subsets[i] = new Subset();
 
        // 初始化每個(gè)子集的父節(jié)點(diǎn)和秩
        for (int v = 0; v < V; ++v) {
            subsets[v].parent = v;
            subsets[v].rank = 0;
        }
 
        // 取E-1條邊
        int i = 0;
        while (e < V - 1) {
            Edge next_edge = new Edge();
            next_edge = edge[i++];
 
            int x = find(subsets, next_edge.src);
            int y = find(subsets, next_edge.dest);
 
            // 如果兩個(gè)節(jié)點(diǎn)不在同一個(gè)集合中,合并它們
            if (x != y) {
                result[e++] = next_edge;
                union(subsets, x, y);
            }
        }
 
        // 打印結(jié)果
        System.out.println("Following are the edges in the constructed MST");
        for (i = 0; i < e; ++i){
            System.out.println(result[i].src + " - " + result[i" - " + result[i].weight);
            return;
        }
        
        // 定義一個(gè)輔助函數(shù),用于查找結(jié)點(diǎn)所在的集合 
        private int find(int parent[], int i) { 
            if (parent[i] == -1) 
                return i; 
            return find(parent, parent[i]); 
        }

        // 定義一個(gè)輔助函數(shù),用于合并兩個(gè)集合 
        private void union(int parent[], int x, int y) { 
            int xset = find(parent, x); 
            int yset = find(parent, y); 
            parent[xset] = yset; 
        } 
    }
}

函數(shù)使用Arrays類的sort方法,按照邊的權(quán)重從小到大對(duì)邊進(jìn)行排序。然后,函數(shù)依次遍歷排序后的邊,對(duì)于每條邊,使用find函數(shù)查找其src和dest所在的集合的根節(jié)點(diǎn)。如果根節(jié)點(diǎn)不同,則說明這兩個(gè)集合不連通,可以合并,并將邊加入最小生成樹的結(jié)果數(shù)組result中。最后,函數(shù)遍歷最小生成樹的結(jié)果數(shù)組result,并輸出每條邊的起點(diǎn)、終點(diǎn)和權(quán)重。

該實(shí)現(xiàn)中,使用了快速查找集合的方法,即使用并查集來實(shí)現(xiàn)。每個(gè)結(jié)點(diǎn)都有一個(gè)parent數(shù)組,其中parent[i]表示結(jié)點(diǎn)i的父節(jié)點(diǎn),如果parent[i] == -1,則說明結(jié)點(diǎn)i為根節(jié)點(diǎn)。在查找結(jié)點(diǎn)所在的集合時(shí),如果當(dāng)前結(jié)點(diǎn)的父節(jié)點(diǎn)為-1,則說明該結(jié)點(diǎn)為根節(jié)點(diǎn),直接返回;否則,遞歸查找其父節(jié)點(diǎn)所在的集合。在合并兩個(gè)集合時(shí),找到要合并的兩個(gè)集合的根節(jié)點(diǎn),將其中一個(gè)根節(jié)點(diǎn)的父節(jié)點(diǎn)設(shè)為另一個(gè)根節(jié)點(diǎn)的索引,即將一個(gè)集合的根節(jié)點(diǎn)合并到另一個(gè)集合的根節(jié)點(diǎn)下。

這樣實(shí)現(xiàn)的克魯斯卡爾算法時(shí)間復(fù)雜度為O(ElogE),其中E表示圖中的邊數(shù),主要的時(shí)間開銷在于排序邊的過程。空間復(fù)雜度為O(V+E),其中V表示圖中的頂點(diǎn)數(shù),主要的空間開銷在于存儲(chǔ)邊和parent數(shù)組。

到此這篇關(guān)于Java實(shí)現(xiàn)克魯斯卡爾算法的示例代碼的文章就介紹到這了,更多相關(guān)Java克魯斯卡爾算法內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • idea遠(yuǎn)程debug調(diào)試部署在tomcat上項(xiàng)目

    idea遠(yuǎn)程debug調(diào)試部署在tomcat上項(xiàng)目

    本文主要介紹了idea遠(yuǎn)程debug調(diào)試部署在tomcat上項(xiàng)目,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-08-08
  • @Async注解的使用以及注解失效問題的解決

    @Async注解的使用以及注解失效問題的解決

    在Spring框架中,@Async注解用于聲明異步任務(wù),可以修飾類或方法,使用@Async時(shí),必須確保方法為public,且類為Spring管理的Bean,啟用異步任務(wù)需要在主類上添加@EnableAsync注解,默認(rèn)線程池為SimpleAsyncTaskExecutor
    2024-09-09
  • SpringBoot中自定義首頁(yè)(默認(rèn)頁(yè))及favicon的方法

    SpringBoot中自定義首頁(yè)(默認(rèn)頁(yè))及favicon的方法

    這篇文章主要介紹了SpringBoot中如何自定義首頁(yè)(默認(rèn)頁(yè))及favicon,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-08-08
  • intellij idea 將模塊打jar包的步驟詳解

    intellij idea 將模塊打jar包的步驟詳解

    這篇文章主要介紹了intellij idea 將模塊打jar包的步驟,本文圖文并茂給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2018-09-09
  • Java通過CMD方式讀取注冊(cè)表任意鍵值對(duì)代碼實(shí)踐

    Java通過CMD方式讀取注冊(cè)表任意鍵值對(duì)代碼實(shí)踐

    這篇文章主要介紹了Java通過CMD方式讀取注冊(cè)表任意鍵值對(duì)代碼實(shí)踐,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,,需要的朋友可以參考下
    2019-06-06
  • SpringBoot Web詳解靜態(tài)資源規(guī)則與定制化處理

    SpringBoot Web詳解靜態(tài)資源規(guī)則與定制化處理

    這篇文章主要介紹了SpringBoot web場(chǎng)景的靜態(tài)資源規(guī)則與定制化,文章圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,需要的小伙伴可以參考一下
    2022-06-06
  • Java中終止線程的方法詳解

    Java中終止線程的方法詳解

    這篇文章主要介紹了Java中終止線程的方法詳解的相關(guān)資料,需要的朋友可以參考下
    2017-05-05
  • XSS攻擊以及java應(yīng)對(duì)xss攻擊的解決方案

    XSS攻擊以及java應(yīng)對(duì)xss攻擊的解決方案

    XSS是跨站腳本攻擊Cross Site Scripting的縮寫,為了和層疊樣式表CSS加以區(qū)分,因此將跨站腳本攻擊縮寫為XSS,這篇文章主要給大家介紹了關(guān)于XSS攻擊以及java應(yīng)對(duì)xss攻擊的解決方案,需要的朋友可以參考下
    2024-02-02
  • Java可重入鎖的實(shí)現(xiàn)原理與應(yīng)用場(chǎng)景

    Java可重入鎖的實(shí)現(xiàn)原理與應(yīng)用場(chǎng)景

    今天小編就為大家分享一篇關(guān)于Java可重入鎖的實(shí)現(xiàn)原理與應(yīng)用場(chǎng)景,小編覺得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來看看吧
    2019-01-01
  • springboot+vue實(shí)現(xiàn)Minio文件存儲(chǔ)的示例代碼

    springboot+vue實(shí)現(xiàn)Minio文件存儲(chǔ)的示例代碼

    本文主要介紹了springboot+vue實(shí)現(xiàn)Minio文件存儲(chǔ)的示例代碼,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2024-02-02

最新評(píng)論

南通市| 湖北省| 西乌| 长葛市| 宜兰市| 无锡市| 方城县| 仁怀市| 灵山县| 长宁县| 六安市| 定陶县| 宝清县| 文水县| 北京市| 疏附县| 合山市| 个旧市| 广州市| 分宜县| 泸西县| 东海县| 年辖:市辖区| 天峻县| 潼南县| 偏关县| 长沙县| 综艺| 樟树市| 闽侯县| 宁陕县| 信阳市| 梓潼县| 勐海县| 屏东市| 杭锦后旗| 湄潭县| 定兴县| 准格尔旗| 莆田市| 含山县|