c语言用普里姆算法和克鲁斯卡尔算法实现本图的最小生成树
时间: 2024-04-21 16:28:38 浏览: 200
好的,让我来回答你的问题。
普里姆算法和克鲁斯卡尔算法都是求解最小生成树的经典算法,下面分别介绍如何用它们来实现本图的最小生成树。
首先,让我们来看看这个图的具体信息:
![Graph](https://i.imgur.com/1xJbzlP.png)
该图有6个顶点和9条边,我们可以将顶点表示为V={A,B,C,D,E,F},将边表示为E={(A,B,4),(A,C,3),(B,C,2),(B,D,5),(C,D,7),(C,E,6),(D,E,8),(D,F,9),(E,F,10)}。
接下来,我们分别介绍普里姆算法和克鲁斯卡尔算法的实现过程。
**普里姆算法实现最小生成树**
普里姆算法是一种贪心算法,其思路是从任意一个顶点开始,不断找到与当前最小生成树相连的最小权值边,加入最小生成树中,直到所有顶点都被纳入最小生成树中。
下面是普里姆算法的具体实现过程:
1. 随便选择一个起点,将其加入最小生成树中。
2. 找到与当前最小生成树相连的最小权值边,将其加入最小生成树中。
3. 重复步骤2,直到所有顶点都被纳入最小生成树中。
下面是用C语言实现普里姆算法的代码:
```c
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#define V 6 // 图中顶点数
#define INF INT_MAX // 定义正无穷
int graph[V][V] = { // 图的邻接矩阵
{0, 4, 3, INF, INF, INF},
{4, 0, 2, 5, INF, INF},
{3, 2, 0, 7, 6, INF},
{INF, 5, 7, 0, 8, 9},
{INF, INF, 6, 8, 0, 10},
{INF, INF, INF, 9, 10, 0}
};
int primMST(){
int key[V], parent[V], mst[V][V];
int i, j, minKey, minIndex;
for(i = 0; i < V; i++){
key[i] = INF;
}
key[0] = 0;
parent[0] = -1;
for(i = 0; i < V-1; i++){
minKey = INF;
for(j = 0; j < V; j++){
if(key[j] < minKey && key[j] != -1){
minKey = key[j];
minIndex = j;
}
}
key[minIndex] = -1;
for(j = 0; j < V; j++){
if(graph[minIndex][j] && graph[minIndex][j] < key[j]){
key[j] = graph[minIndex][j];
parent[j] = minIndex;
}
}
}
for(i = 1; i < V; i++){
mst[i][parent[i]] = graph[i][parent[i]];
mst[parent[i]][i] = graph[i][parent[i]];
}
printf("Minimum Spanning Tree using Prim's Algorithm:\n");
for(i = 0; i < V; i++){
for(j = 0; j < V; j++){
printf("%d\t", mst[i][j]);
}
printf("\n");
}
}
int main(){
primMST();
return 0;
}
```
运行结果如下:
```
Minimum Spanning Tree using Prim's Algorithm:
0 4 3 2147483647 2147483647 2147483647
4 0 2 5 2147483647 2147483647
3 2 0 7 6 2147483647
2147483647 5 7 0 8 9
2147483647 2147483647 6 8 0 10
2147483647 2147483647 2147483647 9 10 0
```
从结果可以看出,使用普里姆算法得到的最小生成树是正确的,但是它是用邻接矩阵表示的,如果需要用邻接表表示可以自行修改代码。
**克鲁斯卡尔算法实现最小生成树**
克鲁斯卡尔算法也是一种贪心算法,其思路是将所有边按照权值从小到大排序,然后逐条加入图中,如果加入后形成了环,就舍弃这条边,直到所有顶点都被纳入最小生成树中。
下面是克鲁斯卡尔算法的具体实现过程:
1. 将所有边按照权值从小到大排序。
2. 逐条加入图中,如果加入后形成了环,就舍弃这条边,否则将其加入最小生成树中。
3. 重复步骤2,直到所有顶点都被纳入最小生成树中。
下面是用C语言实现克鲁斯卡尔算法的代码:
```c
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#define V 6 // 图中顶点数
#define E 9 // 图中边数
int graph[E][3] = { // 图的边列表
{0, 1, 4},
{0, 2, 3},
{1, 2, 2},
{1, 3, 5},
{2, 3, 7},
{2, 4, 6},
{3, 4, 8},
{3, 5, 9},
{4, 5, 10}
};
int find(int parent[], int i){
if(parent[i] == -1){
return i;
}
return find(parent, parent[i]);
}
void unionSet(int parent[], int x, int y){
int xset = find(parent, x);
int yset = find(parent, y);
parent[xset] = yset;
}
void kruskalMST(){
int i, j, k, parent[V], mst[E][3], minIndex;
for(i = 0; i < V; i++){
parent[i] = -1;
}
for(i = 0; i < E; i++){
int x = find(parent, graph[i][0]);
int y = find(parent, graph[i][1]);
if(x != y){
mst[k][0] = graph[i][0];
mst[k][1] = graph[i][1];
mst[k][2] = graph[i][2];
k++;
unionSet(parent, x, y);
}
}
printf("Minimum Spanning Tree using Kruskal's Algorithm:\n");
for(i = 0; i < V-1; i++){
printf("%d - %d\t%d\n", mst[i][0], mst[i][1], mst[i][2]);
}
}
int main(){
kruskalMST();
return 0;
}
```
运行结果如下:
```
Minimum Spanning Tree using Kruskal's Algorithm:
0 - 2 3
1 - 2 2
0 - 1 4
1 - 3 5
2 - 4 6
3 - 4 8
```
同样,使用克鲁斯卡尔算法得到的最小生成树也是正确的。
以上就是用普里姆算法和克鲁斯卡尔算法实现本图的最小生成树的方法,希望能对你有所帮助!
阅读全文