Kruskal 알고리즘 애니메이션 시연 애니메이션으로 코드를 시각화하세요

图码-数据结构可视化动画版

在克鲁斯卡尔算法中,按升序对给定图的所有边进行排序。 如果新添加的边不形成环,则继续在MST中添加新的边和节点。 它首先选择最小加权边,最后选择最大加权边。 因此我们可以说它在每一步中都做出局部最优选择以找到最优解。 因此这是一个 贪婪算法

最小生成树 (MST) 或带权连通无向图的最小权重生成树是权重小于或等于所有其他生成树权重的生成树。 要了解有关最小生成树的更多信息,请参阅 这篇文章

克鲁斯卡尔算法简介:

在这里,我们将讨论 Kruskal 算法 来查找给定加权图的 MST。 

如何使用Kruskal算法求MST?

以下是使用 Kruskal 算法查找 MST 的步骤:

  1. 按权重非降序对所有边进行排序。 
  2. 选择最小的边。 检查是否与目前形成的生成树形成环。 如果未形成循环,则包括该边。 否则,丢弃它。 
  3. 重复步骤#2,直到生成树中有 (V-1) 条边。

步骤2 使用 并查算法 来检测循环。 

因此,我们建议您先阅读以下文章作为先决条件。 

  • 并查算法| 第 1 组(检测图中的循环)  
  • 并查算法| 设置 2(按等级和路径压缩联合)

Kruskal 寻找最小成本生成树的算法使用贪心方法。 贪心选择是在目前构建的 MST 中选择不会引起循环的最小权重边。 让我们通过一个例子来理解它:

插图:

下面是上述方法的图示:

输入图:
 

Kruskal 的最小生成树算法

该图包含 9 个顶点和 14 条边。 因此,形成的最小生成树将具有 (9 – 1) = 8 个边。 
排序后:

重量 来源 目的地
1 7 6
2 8 2
2 6 5
4 0 1
4 2 5
6 8 6
7 2 3
7 7 8
8 0 7
8 1 2
9 3 4
10 5 4
11 1 7
14 3 5

现在从已排序的边列表中一一挑选所有边 

步骤1: 选取边7-6。 没有形成循环,包括它。 

在MST中添加边7-6

在MST中添加边7-6

步骤2: 选取边8-2。 没有形成循环,包括它。   

在MST中添加边8-2

在MST中添加边8-2

步骤3: 选取边6-5。 没有形成循环,包括它。 

在 MST 中添加边 6-5

在 MST 中添加边 6-5

步骤 4: 选取边 0-1。 没有形成循环,包括它。

在MST中添加边0-1

在MST中添加边0-1

步骤5: 选取边2-5。 没有形成循环,包括它。

在MST中添加边0-1

在 MST 中添加边 2-5

第6步: 选取边8-6。 由于包含该边会导致循环,因此将其丢弃。 拾取边2-3: 未形成循环,包含它。

在 MST 中添加边 2-3

在 MST 中添加边 2-3

步骤7: 选取边7-8。 由于包含该边会导致循环,因此将其丢弃。 选边 0-7。 没有形成循环,包括它。

在 MST 中添加边 0-7

在 MST 中添加边 0-7

第8步: 选取边1-2。 由于包含该边会导致循环,因此将其丢弃。 选取边 3-4。 没有形成循环,包括它。

在MST中添加边3-4

在MST中添加边3-4

注: 由于MST包含的边数等于(V – 1),所以算法到此停止

下面是上述方法的实现:

C++

// C++ program for the above approach
  
#include <bits/stdc++.h>
using namespace std;
  
// DSU data structure
// path compression + rank by union
class DSU {
    int* parent;
    int* rank;
  
public:
    DSU(int n)
    {
        parent = new int[n];
        rank = new int[n];
  
        for (int i = 0; i < n; i++) {
            parent[i] = -1;
            rank[i] = 1;
        }
    }
  
    // Find function
    int find(int i)
    {
        if (parent[i] == -1)
            return i;
  
        return parent[i] = find(parent[i]);
    }
  
    // Union function
    void unite(int x, int y)
    {
        int s1 = find(x);
        int s2 = find(y);
  
        if (s1 != s2) {
            if (rank[s1] < rank[s2]) {
                parent[s1] = s2;
            }
            else if (rank[s1] > rank[s2]) {
                parent[s2] = s1;
            }
            else {
                parent[s2] = s1;
                rank[s1] += 1;
            }
        }
    }
};
  
class Graph {
    vector<vector<int> > edgelist;
    int V;
  
public:
    Graph(int V) { this->V = V; }
  
    // Function to add edge in a graph
    void addEdge(int x, int y, int w)
    {
        edgelist.push_back({ w, x, y });
    }
  
    void kruskals_mst()
    {
        // Sort all edges
        sort(edgelist.begin(), edgelist.end());
  
        // Initialize the DSU
        DSU s(V);
        int ans = 0;
        cout << "Following are the edges in the "
                "constructed MST"
             << endl;
        for (auto edge : edgelist) {
            int w = edge[0];
            int x = edge[1];
            int y = edge[2];
  
            // Take this edge in MST if it does
            // not forms a cycle
            if (s.find(x) != s.find(y)) {
                s.unite(x, y);
                ans += w;
                cout << x << " -- " << y << " == " << w
                     << endl;
            }
        }
        cout << "Minimum Cost Spanning Tree: " << ans;
    }
};
  
// Driver code
int main()
{
    Graph g(4);
    g.addEdge(0, 1, 10);
    g.addEdge(1, 3, 15);
    g.addEdge(2, 3, 4);
    g.addEdge(2, 0, 6);
    g.addEdge(0, 3, 5);
  
    // Function call
    g.kruskals_mst();
  
    return 0;
}


            

C

Java

Python3

C#

Javascript

输出

以下是构建的 MST 中的边
2 -- 3 == 4
0 -- 3 == 5
0 -- 1 == 10
最小成本生成树:19

时间复杂度: O(E * logE) 或 O(E * logV) 

  • 边排序需要 O(E * logE) 时间。 
  • 排序后,我们迭代所有边并应用查找并集算法。 查找和并集操作最多需要 O(logV) 时间。
  • 所以总体复杂度是 O(E * logE + E * logV) 时间。 
  • E的值最多可以是O(V 2 ),因此O(logV)和O(logE)是相同的。 因此,总体时间复杂度为 O(E * logE) 或 O(E*logV)

辅助空间: O(V + E),其中V是图中的顶点数,E是图中的边数。

本文由 Aashish Barnwal编译 ,并由 图码 团队审核。 如果您发现任何不正确的内容,或者您​​想分享有关上述主题的更多信息,请发表评论。

시험 합격, 직업 발전, 또는 순수한 관심 등 어떤 목표를 가지고 있든, 이 데이터 구조 및 알고리즘 시각화 웹사이트는 귀중한 자원이 될 것입니다.

이 웹사이트로 이동하여 학습 여정을 시작하세요!

다음은 일반적인 것들입니다: 【C 언어 설명】《데이터 구조와 알고리즘》데이터 구조 JAVA 구현 데이터 구조와 알고리즘 기초 (칭다오 대학 - 왕줘) 데이터 구조와 알고리즘 왕도 데이터 구조 C 언어 구현 속성 데이터 구조 기말고사 전 구급 데이터 구조 비디오 C 언어판 튜토리얼 데이터 구조 옌웨이민 데이터 구조 하오빈 데이터 구조 대학원 시험 JAVA 데이터 구조 알고리즘과 기초 데이터 구조 왕도 2022 데이터 구조 학습 데이터 구조 샤오자위 왕줘 데이터 구조 학습 데이터 구조 저장 대학 데이터 구조 복습 데이터 구조 마사빙 데이터 구조 기초 제로 데이터 구조와 알고리즘 데이터 구조 입문 대학원 시험 데이터 구조 문제 풀이 설명 데이터 구조 기말 복습 컴퓨터 2급