正在载入交互式动画窗口请稍等

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数据结构学习 数据结构小甲鱼 王卓 学习数据结构 数据结构浙江大学 数据结构复习 数据结构马士兵 数据结构零基础教程 数据结构和算法 数据结构入门 考研数据结构习题讲解 数据结构期末复习 计算机二级