Kruskal算法求最小生成树的c++代码实现

kruskal算法是一类适用于稀疏图的最小生成树算法,主要思想也很简单,将所有的边分为 属于生成树的边S和不属于的V-S ,每次在V-S中找一个权值最小的边放入S中,同时该边不构成回路,关于是否构成回路,可以使用并查集来判断。比如


上图中假如{1,2} , {1,3}都已经属于,那么unionSet[3]  = unionSet[2] = unionSet[1] = 1;这时如果想加入{1,3},此时unionSet[2] == unionSet[1] 则会构成回路。

循环的终止条件是放入S中的边的个数等于 顶点个数-1.

#include <iostream>
#include<vector>
#include<queue>
using namespace std;

struct Edge{
    int startP;
    int endP;
    int weight;
    Edge(int s, int e, int w):startP(s), endP(e), weight(w){};
};

struct cmp{
    bool operator() (Edge e1, Edge e2) const{
        return e1.weight >= e2.weight;
    }
};

int find(const vector<int>& unionSet, int index) //通过并查集找到index所属的类别
{
    while( unionSet[index] != index){
        index = unionSet[index];
    }
    return index;
}

vector<Edge>  Kruskal(  priority_queue<Edge, vector<Edge>, cmp> edges, vector<int> unionSet){
    int num_points = unionSet.size();
    vector<Edge> MST;
    while( MST.size() < num_points -1){ //当MST的size 等于点的个数-1的时候完成生成最小生成树
        if(  find(unionSet, edges.top().startP) != find(unionSet, edges.top().endP)  ) //如果起点终点属于同一类,则构成回路
        {
            MST.push_back(edges.top());
            unionSet[ find(unionSet, edges.top().endP )] = find(unionSet, edges.top().startP );
        }
        edges.pop();
    }
    return MST;
}
void show(const vector<Edge>& MST){ //显示函数
    for(int i = 0; i < MST.size(); i++)
        cout << MST[i].startP+1 << "->" << MST[i].endP+1 << endl;
}

int main()
{
    
    Edge Edge_array[10] = {Edge(0,1,6), Edge(0,2,1), Edge(0,3,5), Edge(1,2,5), Edge(1,4,3), Edge(2,3,5),Edge(2,4,6), Edge(2,5,4), Edge(3,5,2), Edge(4,5,6)};
    priority_queue<Edge, vector<Edge>, cmp> Edgs_pq;
    for(int i = 0; i < 10; i++)
        Edgs_pq.push(Edge_array[i]); //初始化优先队列,将各个边按照权值从小到大放入优先队列中
    vector<int> unionSet( 6 , -1 ); 
    for(int i = 0; i < 6; i++)
        unionSet[i] = i; //初始化并查集

    vector<Edge> MST = Kruskal(Edgs_pq, unionSet);
    show(MST);



    return 0;
}
结果按照先后顺序依次输出放入的边,如下:

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值