最小生成树构造算法--Prim算法,Kruskal算法(C语言)

最小生成树

最小生成树(minimum spanning tree)是由n个顶点,n-1条边,将一个连通图连接起来,且使权值最小的结构。
最小生成树可以用Prim(普里姆)算法或kruskal(克鲁斯卡尔)算法求出。

我们将以下面的带权连通图为例讲解这两种算法的实现:
带权连通图

注:由于测试输入数据较多,程序可以采用文件输入
这里写图片描述



Prim(普里姆)算法
时间复杂度:O(N^2)(N为顶点数)
prim算法又称“加点法”,用于边数较多的带权无向连通图
方法:每次找与之连线权值最小的顶点,将该点加入最小生成树集合中
注意:相同权值任选其中一个即可,但是不允许出现闭合回路的情况。
1
2
3
4
5
6
7

代码部分通过以下步骤可以得到最小生成树:

1.初始化:
lowcost[i]:表示以i为终点的边的最小权值,当lowcost[i]=0表示i点加入了MST。
mst[i]:表示对应lowcost[i]的起点,当mst[i]=0表示起点i加入MST。
由于我们规定最开始的顶点是1,所以lowcost[1]=0,MST[1]=0。即只需要对2~n进行初始化即可。

#define MAX 100  
#define MAXCOST 0x7fffffff  
  
int graph[MAX][MAX];  
  
void prim(int graph[][MAX], int n)  
{  
    int lowcost[MAX];  
    int mst[MAX];  
    int i, j, min, minid, sum &#
Prim算法是一种用于求解最小生成树的经典算法,它的基本思想是从一个顶点开始,逐步扩展生成树的边,直到覆盖所有的顶点。下面是Prim算法C语言实现: ```c #include <stdio.h> #include <stdbool.h> #define INF 9999 #define V 5 int minKey(int key[], bool mstSet[]) { int min = INF, min_index; for (int v = 0; v < V; v++) { if (mstSet[v] == false && key[v] < min) { min = key[v]; min_index = v; } } return min_index; } void printMST(int parent[], int graph[V][V]) { printf("Edge \tWeight\n"); for (int i = 1; i < V; i++) { printf("%d - %d \t%d \n", parent[i], i, graph[i][parent[i]]); } } void primMST(int graph[V][V]) { int parent[V]; int key[V]; bool mstSet[V]; for (int i = 0; i < V; i++) { key[i] = INF; mstSet[i] = false; } key[0] = 0; parent[0] = -1; for (int count = 0; count < V - 1; count++) { int u = minKey(key, mstSet); mstSet[u] = true; for (int v = 0; v < V; v++) { if (graph[u][v] && mstSet[v] == false && graph[u][v] < key[v]) { parent[v] = u; key[v] = graph[u][v]; } } } printMST(parent, graph); } int main() { int graph[V][V] = { {0, 2, 0, 6, 0}, {2, 0, 3, 8, 5}, {0, 3, 0, 0, 7}, {6, 8, 0, 0, 9}, {0, 5, 7, 9, 0} }; primMST(graph); return 0; } ``` 这段代码实现了Prim算法的逻辑。首先定义了一个`minKey`函数,用于找到key值最小的顶点。然后定义了`printMST`函数,用于打印最小生成树的边和权重。接着是`primMST`函数,其中初始化了key、mstSet和parent数组,并进行了主要的Prim算法逻辑。最后,在`main`函数中定义了一个的邻接矩阵,并调用`primMST`函数求解最小生成树
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值