Анимационная демонстрация алгоритма Крускала Визуализируйте свой код с помощью анимации

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

在克鲁斯卡尔算法中,按升序对给定图的所有边进行排序。 如果新添加的边不形成环,则继续在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