Prim与Kruskal算法在两种存储结构下的实现

本文介绍了Prim和Kruskal算法用于寻找带权无向连通图的最小生成树。Kruskal算法适合边稀疏图,Prim算法适合边稠密图。Kruskal算法通过避免回路选取最小权值边,Prim算法则每次选取与当前MST距离最近的顶点。文章详细描述了两种算法的基本思想、正确性、实现细节,并提供了邻接矩阵和邻接表两种存储结构的实现方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

如题 自用笔记 如有错误欢迎及时指正

所用存储结构与基本操作见下文

https://blog.csdn.net/weixin_46127065/article/details/120631629?spm=1001.2014.3001.5502

        对于求取任意一个带权无向连通图的最小生成树的问题,在要求总的权值最小的情况下,最直接的想法就是将连通网中的所有边按照权值大小进行升序排序,从小到大依次选择。由于最小生成树本身是一棵生成树,一颗最小生成树必然满足以下两点:

        a).树中任意顶点之间有且仅有一条路径,即树中不能存在回路;

        b.)具有n个顶点的连通图,其最小生成树中只能有 n-1 条边,这 n-1 条边连通着 n 个顶点;

Kruskal算法

基本思想

        算法每轮选取与已求出的MST不构成回路的最小权值边,直到图变为n个顶点n-1条边的连通图为止。

        设图中有e条边,其时间性能为O(eloge) ,是对边归并的算法,适合边稀疏图求取MST。

算法描述与正确性

        描述:

        1.将边按照权值从小到大排列;

        2.遍历第一条边并将其加入MST里,判断是否出现回路;

        3.如果出现回路则跳过,否则将该边加入MST;

        4.继续遍历其余边验证,直到所有的边都遍历完;

        正确性:

        将边按权值大小排序完成后,将第一条边加入MST后,必然得到一颗MST,加入第二条边时,MST依旧成立。

        加入第三条边时,若三条边形成回路,则略过该边,已知边集合已按权值从小到大排序,此时MST仍然成立,若加入第三条边不形成回路时,将其直接加入MST,MST仍然成立。

        综上,在n个顶点图中遍历n-1条边后,必然求出一颗MST。

实现时要做的工作

        1.获取图中所有边,需要一个结构体和数组来保存;

        2.边从小到大排序,方便之后归并;

        3.判定已选边是否构成回路(有多种方法,为便于讨论仅给出一个);

           判定回路方法:设置两个变量保存当前所选边的起始顶点与结尾顶点下标,找到这两个顶点在已求出MST中的终点下标,比较两者的终点下标是否相等,相等则加入该边到MST中会出现回路,否则加入该边到MST中不会出现回路。

辅助工具

//辅助结构体
typedef struct EdgeData{
    VertexType start;       //边起始顶点
    VertexType end;         //边结尾顶点
    int weight;             //边权值
} EData;

//按权值从小到大对边排序
void SortEdges(EData *edges, int length){
    int i,j;
    for (i=0; i<length; i++){
        for (j=i+1; j<length; j++){
            if (edges[i].weight > edges[j].weight){
                // 交换"第i条边"和
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值