最小生成树算法 -- Prim算法与Kruskal算法

1、什么是最小生成树

(1)是一棵树

  • 无回路
  • |v| 个顶点一定有 |v| - 1条边

(2)是生成树

  • 包含全部顶点
  • |v| - 1条边都在图里

(3)边的权重和最小

2、Prim算法 – 让一棵小树长大

Prim算法其实就是改进的dijkstra算法。Prim算法是先选择一个点作为源点,然后根据其它点到源点s的最小距离,逐步收录其它顶点。收录的过程是按照顶点来进行收录的。

/*
    Prim算法 -- 让一个小树长大,逐步收录每一条最小边
*/

void Prim() {
    MTS = {s}; // 随便选择一个点作为源点s,然后收录
    while (1) {
        v = 未收录顶点中的最小值;
        if (v不存在) {
            break;
        }
        将v收录进MTS中,dist[v] = 0;
        for (v的每个邻接点w) {
            if (dist[w] != 0) {
                if (dist[w] > edge[w][v]) {
                    dist[w] = edge[w][v];
                    parent[w] = v;  // 表示在生成树中,w连接到节点v
                }
            }
        }
    }
    if (MTS中收录的顶点个数小于|v|) {
        cout << "生成树不存在\n";
    }
}

2、Kruskal算法 – 将森林合并成树

与Prim算法不同的是,Kruskal算法每次选择的都是边,每次将权重最小的边加入,如果不构成回路,那么就认为是一条有效边。最终判断有效边的数量是否为|v| - 1。

void Kruskal(Graph G) {
    MTS = {};
    while (MTS中不到|v| - 1条边 && E中还有边) {
        从E中选择一条权重最小的边E(v,w);    // 可以利用最小堆E(v, w)从E中删除;
        if (E(v, w)不在MTS中构成回路)       // 回路判断:并查集
        {E(v,w)加入到MTS;
        }
    }
    if (MTS中不到 |v| - 1条边) {
        cout << "生成树不存在\n";
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值