图-普里姆(Prim)算法记录

本文详细介绍了普里姆算法在无向有权连通图中寻找最小生成树的过程。通过具体的步骤解析,配合示例图与访问结果,清晰地展示了算法的工作原理及实现方式。

普里姆(Prim)算法记录

参考资料:《大话数据结构》
prim算法是在无向有权连通图中找到最小生成树;
先把自己用excel做的流程和访问结果截图给出来,然后语言描述,然后再贴《大话数据结构》书中代码!
这里写图片描述
原图:
拓扑图
访问结果:
结果
两个数组:

int adjvx[9];   //保存的是能到lowcost数组中最短权值结点的结点下标
int lowcost[9]; //adjvx数组中各个结点到“能到达”结点的最短路径,值为0表示已经访问

开始流程(将v0作为第一个访问结点示例)

第一轮:
a)访问v0,将lowcost[0]=0;【标识v0已经访问过了】
b)查找与v0相连的结点,将对应相连的权值写到lowcost[]数组(不可达我用的是【~】标识),将能到此节点的结点下标写到adjvex[]数组,例如:到v1的结点路径长度为10,所以lowcost[1]=10;adjvex[1]=0【表示v1可以通过v0到达】;到v5的结点也是如此!

第二轮:
a)在上一轮的lowcost数组中,查找以一个最小值,访问该值对应的结点;
例如:上一轮lowcost数组中最小值是10,对应下标为v1,访问v1;将lowcost[1]=0;【标识v1已经访问过了】
b)查找与v1相连的结点,将对应相连的权值写到lowcost[]数组,将能到此节点【也就是v1】的结点下标写到adjvex[]数组;
例如:v1能到v2,权值为18,所以lowcost[2]=18;adjvex[2]=1;v1到v6,v1到v8也是类似;

第三轮:
a)在上一轮的lowcost数组中,查找以一个最小值,访问该值对应的结点;
例如:上一轮lowcost数组中最小值是11,对应下标为v5,访问v5;将lowcost[5]=0;【标识v5已经访问过了】
b)查找与v5相连的结点,将对应相连的权值写到lowcost[]数组,将能到此节点【也就是v5】的结点下标写到adjvex[]数组;
注意:v5能到v6,权值为17,与v1到v6权值为16相比,前者要大,所以保留v1到v6的记录,不把v5到v6的数据写进lowcost数组和adjvex数组;其实在每一轮做这一步的时候,都要比较此次访问的结点到相连结点,在此之前的访问过程中,是否有更短的权值路径,有的话,则保留原记录!
v5能到v4,将此记录写到lowcost数组和adjvex数组!

第四轮:
a)在上一轮的lowcost数组中,查找以一个最小值,访问该值对应的结点;
例如:上一轮lowcost数组中最小值是12,对应下标为v8,访问v8;将lowcost[8]=0;【标识v8已经访问过了】
b)查找与v8相连的结点,将对应相连的权值写到lowcost[]数组,将能到此节点【也就是v8】的结点下标写到adjvex[]数组;
例如:v8到v2,v8到v3;
。。。。。。
后面的就可以自己模拟了

源码:

void MiniSpanTree_Prim(MGraph G)
{
    int min, i, j, k;
    int adjvex[MAXVEX];
    int lowcost[MAXVEX];
    lowcost[0] = 0;
    adjvex[0] = 0;
    for(i = 1; i<G.numVertexes;i++)
    {
        lowcost[i] = G.arc[0][i];
        adjvex[i] = 0;
    }
    for(i = 1; i<G.numVertexes;i++)
    {
        min = INFINITY;
        j = 1; 
        k = 1;
        while(j<G.numVertexes)
        {
            if(lowcost[j]!=0 && lowcost[j]<min)
            {
                min = lowcost[j];
                k = j;
            }
            j++;
        }
        printf("(%d,%d)",adjvex[k],k);
        lowcost[k] = 0;
        for(j = 1; j<G.numVertexes; j++)
        {
            if(lowcost[j]!=0 && G.arc[k][j]<lowcost[j])
            {
                lowcost[j] = G.arc[k][j];
                adjvex[j] = k;
            }
        }
    }
}
### 普里姆算法概述 普里姆算法是一种用于寻找加权连通中最小生成树的经典算法。该算法通过逐步扩展一棵初始为空的树,最终覆盖所有节点并使得总权重达到最小[^1]。 ### 算法原理 此算法的核心在于维护两个集合:一个是已经加入到当前正在构建的最小生成树中的顶点;另一个则是尚未被纳入考虑范围内的剩余顶点。每次迭代过程中都会从未处理过的邻接边上选取具有最低成本的一条连接至现有部分,从而不断壮大这棵成长中的树形结构直到遍历整个网络为止[^2]。 ### 实现方式 下面给出Python版本的具体实现: ```python import sys def prim(graph): n = len(graph) key = [sys.maxsize]*n parent = [-1]*n mstSet = [False]*n key[0]=0 result=[] for count in range(n-1): u=minKey(key,mstSet,n) mstSet[u]=True for v in range(n): if graph[u][v]>0 and not mstSet[v]and graph[u][v]<key[v]: parent[v]=u key[v]=graph[u][v] for i in range(1, n): result.append((parent[i],i,graph[parent[i]][i])) return result def minKey(key, mstSet,n): min_val=sys.maxsize min_index=-1 for v in range(n): if (not mstSet[v]) and key[v]<min_val: min_val=key[v] min_index=v return min_index ``` 这段代码定义了一个`prim()`函数接收一个表示无向带权的二维列表作为输入参数,并返回由三元组组成的列表形式的结果,其中每个元素代表一条边及其两端结点编号以及对应的代价值[^4]。 ### 应用场景 在实际生活中有许多地方需要用到此类技术解决问题,比如城市规划部门为了节省电缆铺设费用,在设计电力传输线路布局方案时就可以借助于它来找到最优路径组合;还有电信运营商建设基站之间的微波通信链路同样适用于此种策略以降低整体造价开销等等[^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值