首页 > 后端开发 > C++ > 正文

c++中如何实现Kruskal算法_c++ Kruskal算法实现方法

冰火之心
发布: 2025-09-26 19:12:02
原创
770人浏览过
Kruskal算法通过排序边和并查集检测环,逐步选择最小权重边构建最小生成树。首先定义边结构体并按权重排序,使用并查集判断顶点连通性,避免成环。初始化每个顶点的父节点为自身,遍历排序后的边,若两端点不在同一集合,则加入生成树并合并集合。最终得到包含所有顶点的无环连通子图。该方法时间复杂度为O(E log E),适用于稀疏图。示例中5个顶点6条边,经排序与并查集处理后输出最小生成树各边及其权重。核心在于贪心策略与高效连通性检查的结合。

c++中如何实现kruskal算法_c++ kruskal算法实现方法

Kruskal算法用于求解无向图的最小生成树(MST),核心思想是按边的权重从小到大排序,依次选择边并避免形成环,直到生成树包含所有顶点。在C++中,通常结合并查集(Union-Find)来高效判断是否成环。

1. 数据结构设计

需要定义边的结构体,并实现并查集来管理顶点的连通性。

struct Edge {

  int u, v, weight;

立即学习C++免费学习笔记(深入)”;

  Edge(int u, int v, int w) : u(u), v(v), weight(w) {}

};

使用vector存储所有边,并按权重排序:

bool cmp(Edge a, Edge b) {

  return a.weight < b.weight;

}

2. 并查集实现

并查集用于快速查找根节点和合并集合,防止加入边后形成环。

int find(vector<int>& parent, int x) {

  if (parent[x] != x)

    parent[x] = find(parent, parent[x]); // 路径压缩

  return parent[x];

}

void unite(vector<int>& parent, vector<int>& rank, int x, int y) {

  int rootX = find(parent, x);

  int rootY = find(parent, y);

  if (rootX != rootY) {

    if (rank[rootX] < rank[rootY])

      parent[rootX] = rootY;

    else if (rank[rootX] > rank[rootY])

      parent[rootY] = rootX;

    else {

      parent[rootY] = rootX;

      rank[rootX]++;

    }

  }

}

3. Kruskal主函数

将所有边排序后逐个尝试加入生成树,使用并查集检查连接性。

vector<Edge> kruskal(int n, vector<Edge>& edges) {

  vector<Edge> result;

法语写作助手
法语写作助手

法语助手旗下的AI智能写作平台,支持语法、拼写自动纠错,一键改写、润色你的法语作文。

法语写作助手 31
查看详情 法语写作助手

  sort(edges.begin(), edges.end(), cmp);

  vector<int> parent(n);

  vector<int> rank(n, 0);

  // 初始化并查集

  for (int i = 0; i < n; ++i)

    parent[i] = i;

  for (Edge& e : edges) {

    int u = e.u, v = e.v;

    if (find(parent, u) != find(parent, v)) { // 不连通

      result.push_back(e);

      unite(parent, rank, u, v); // 合并集合

    }

  }

  return result;

}

4. 使用示例

假设有5个顶点和6条边:

int main() {

  int n = 5;

  vector<Edge> edges;

  edges.push_back(Edge(0, 1, 2));

  edges.push_back(Edge(0, 3, 6));

  edges.push_back(Edge(1, 2, 3));

  edges.push_back(Edge(1, 3, 8));

  edges.push_back(Edge(1, 4, 5));

  edges.push_back(Edge(2, 4, 7));

  vector<Edge> mst = kruskal(n, edges);

  cout << "最小生成树的边:\n";

  for (Edge& e : mst) {

    cout << e.u << " -- " << e.v << " : " << e.weight << endl;

  }

  return 0;

}

基本上就这些。关键在于边排序和并查集的配合使用,确保每次选的都是当前最短且不会成环的边。时间复杂度主要由排序决定,为 O(E log E),适合稀疏图。

以上就是c++++中如何实现Kruskal算法_c++ Kruskal算法实现方法的详细内容,更多请关注php中文网其它相关文章!

c++速学教程(入门到精通)
c++速学教程(入门到精通)

c++怎么学习?c++怎么入门?c++在哪学?c++怎么学才快?不用担心,这里为大家提供了c++速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载
来源:php中文网
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
最新问题
开源免费商场系统广告
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号