App下載

經(jīng)典Java面試題解析:最小生成樹(shù)

黃色相思情 2023-07-11 09:18:20 瀏覽數(shù) (1766)
反饋

在Java的面試中,最小生成樹(shù)是一個(gè)常見(jiàn)的算法主題。本文將介紹一道經(jīng)典的Java面試題——最小生成樹(shù),并提供詳細(xì)的解析和解題思路。

題目

給定一個(gè)帶權(quán)無(wú)向圖,找到一棵包含所有節(jié)點(diǎn)的最小生成樹(shù)。

解析與解題思路

最小生成樹(shù)是一個(gè)圖論中的重要概念,指的是在無(wú)向圖中找到一棵生成樹(shù),使得所有邊的權(quán)值之和最小。

在解決最小生成樹(shù)問(wèn)題時(shí),我們可以使用貪心算法中的Prim算法或Kruskal算法。

  1. Prim算法:
    首先,我們隨機(jī)選擇一個(gè)節(jié)點(diǎn)作為起始節(jié)點(diǎn),將其加入到最小生成樹(shù)中,并將其標(biāo)記為已訪問(wèn)。
    然后,我們從已訪問(wèn)的節(jié)點(diǎn)集合中選取一個(gè)節(jié)點(diǎn),該節(jié)點(diǎn)到未訪問(wèn)的節(jié)點(diǎn)的邊權(quán)值最小,將這個(gè)邊和對(duì)應(yīng)的未訪問(wèn)節(jié)點(diǎn)加入到最小生成樹(shù)中。
    不斷重復(fù)上述步驟,直到所有節(jié)點(diǎn)都被訪問(wèn)。
  2. Kruskal算法:
    首先,我們將所有邊按照權(quán)值從小到大進(jìn)行排序。
    然后,從權(quán)值最小的邊開(kāi)始遍歷,如果這條邊的兩個(gè)節(jié)點(diǎn)不在同一個(gè)連通分量中,就將這條邊加入到最小生成樹(shù)中,并將這兩個(gè)節(jié)點(diǎn)合并到同一個(gè)連通分量中。
    不斷重復(fù)上述步驟,直到最小生成樹(shù)中包含了所有節(jié)點(diǎn)。

通過(guò)Prim算法或Kruskal算法,我們可以找到一個(gè)包含所有節(jié)點(diǎn)的最小生成樹(shù)。

以下是Java代碼實(shí)例(使用Prim算法):

import java.util.Arrays;

public class MinimumSpanningTree {
    public static int primMST(int[][] graph) {
        int n = graph.length;
        int[] key = new int[n]; // 存儲(chǔ)節(jié)點(diǎn)到最小生成樹(shù)的最小權(quán)值
        boolean[] visited = new boolean[n]; // 記錄節(jié)點(diǎn)是否已訪問(wèn)
        Arrays.fill(key, Integer.MAX_VALUE);

        key[0] = 0; // 選擇第一個(gè)節(jié)點(diǎn)作為起始節(jié)點(diǎn)
        int minCost = 0;

        for (int i = 0; i < n; i++) {
            int u = -1; // 用于存儲(chǔ)當(dāng)前的最小權(quán)值節(jié)點(diǎn)

            for (int v = 0; v < n; v++) {
                if (!visited[v] && (u == -1 || key[v] < key[u])) {
                    u = v;
                }
            }

            visited[u] = true;
            minCost += key[u];

            for (int v = 0; v < n; v++) {
                if (!visited[v] && graph[u][v] != 0 && graph[u][v] < key[v]) {
                    key[v] = graph[u][v];
                }
            }
        }

        return minCost;
    }

    public static void main(String[] args) {
        int[][] graph = {
            {0, 2, 0, 6, 0},
            {2, 0, 3, 8, 5},
            {0, 3, 0, 0, 7},
            {6, 8, 0, 0, 9},
            {0, 5, 7, 9, 0}
        };

        int minCost = primMST(graph);
        System.out.println("最小生成樹(shù)的權(quán)值之和為:" + minCost);
    }
}

結(jié)論

通過(guò)Prim算法或Kruskal算法,我們可以找到一個(gè)包含所有節(jié)點(diǎn)的最小生成樹(shù)。最小生成樹(shù)是面試中常見(jiàn)的算法題目,掌握了解題思路和實(shí)現(xiàn)代碼,我們能夠在面試中更加自信地回答相關(guān)問(wèn)題。

 學(xué)java,就到java編程獅!


0 人點(diǎn)贊