Java Stream API:實現 Kruskal 演算法

banq發表於2024-04-10

使用 Java Stream API 實現最小生成樹的 Kruskal克魯斯卡爾 演算法

Kruskal 演算法是一種流行的方法,用於查詢連通無向圖的最小生成樹 (MST)。該演算法的工作原理是按權重升序選擇邊,同時確保將邊新增到 MST 不會建立迴圈。在這篇博文中,我們將探討如何使用 Java Stream API 實現 Kruskal 演算法。

什麼是克魯斯卡爾Kruskal 演算法
在深入實現之前,我們先簡要討論一下 Kruskal 演算法所涉及的步驟:

  • 1. 對邊進行排序:將圖中的所有邊按照其權重非降序進行排序。
  • 2.初始化MST:建立一個空集來儲存MST的邊。
  • 3. 迭代邊:按排序順序迭代所有邊。對於每條邊:
  •    - 如果將邊新增到 MST 不會建立環路,則將其新增到 MST。
  •    - 否則,丟棄邊緣。
  • 4.輸出MST:新增到MST的邊集合形成最小生成樹。


使用Java Stream API實現
要使用Java Stream API實現Kruskal演算法,我們需要遵循以下步驟:

  • 1. 定義一個類來表示圖中的一條邊,包括源、目的地和權重。
  • 2. 建立一種根據權重對邊進行排序的方法。
  • 3. 實現一種方法來查詢不相交集合中頂點的父級。
  • 4. 使用Java Stream API 實現主要演算法。

讓我們從定義 Edge 類開始:

class Edge {
    int source, destination, weight;

    public Edge(int source, int destination, int weight) {
        this.source = source;
        this.destination = destination;
        this.weight = weight;
    }
}

接下來,我們建立一個方法來根據邊的權重對邊進行排序:

private static List<Edge> sortEdges(List<Edge> edges) {
    return edges.stream()
            .sorted(Comparator.comparingInt(e -> e.weight))
            .collect(Collectors.toList());
}


現在,我們需要實現一種方法來查詢不相交集合中頂點的父級。此方法對於檢測圖中的迴圈至關重要:

private static int findParent(int[] parent, int vertex) {
    if (parent[vertex] == -1)
        return vertex;
    return findParent(parent, parent[vertex]);
}

最後,我們可以使用Java Stream API來實現主要演算法:

public static List<Edge> kruskalMST(List<Edge> edges, int vertices) {
    List<Edge> result = new ArrayList<>();
    List<Edge> sortedEdges = sortEdges(edges);
    int[] parent = new int[vertices];
    Arrays.fill(parent, -1);
    
    sortedEdges.stream().forEach(edge -> {
        int x = findParent(parent, edge.source);
        int y = findParent(parent, edge.destination);

        if (x != y) {
            result.add(edge);
            parent[x] = y;
        }
    });

    return result;
}

使用示例
以下是如何使用 kruskalMST 方法查詢圖的最小生成樹的示例:

public static void main(String[] args) {
    List<Edge> edges = Arrays.asList(
            new Edge(0, 1, 10),
            new Edge(0, 2, 6),
            new Edge(0, 3, 5),
            new Edge(1, 3, 15),
            new Edge(2, 3, 4)
    );
    
    List<Edge> mst = kruskalMST(edges, 4);
    
    System.out.println(<font>"Minimum Spanning Tree:");
    mst.forEach(edge -> System.out.println(edge.source +
" - " + edge.destination + ": " + edge.weight));
}

結論
在這篇博文中,我們討論瞭如何使用 Java Stream API 實現 Kruskal 演算法來查詢圖的最小生成樹。 Java Stream API 提供了一種簡潔且可讀的方式來處理集合,使其成為實現 Kruskal 演算法等演算法的合適選擇。

相關文章