1.随机生成一个无向网要求: (1)无向网G=( V,E),V={A,B,C,D,E,T}:EIl-11,即固定6个顶点11条边;(2)边的权值随机取值范围为[ 1,40 ],11条边的权值不能重复(保证生成树唯一);(3)存储结构使用邻接矩阵。 2.求该无向网的最小生成树要求: (1)用Prim算法求无向网G的最小生成树,给出选择顶点的顺序; (2)用Kruskal算法从顶点A出发求无向网G的最小生成树,给出添加边的顺序;3)计算出最小生成树的代价:C语言代码示例
时间: 2024-02-15 07:05:48 浏览: 78
好的,下面是基于邻接矩阵表示的最小生成树的 C 语言代码示例,包括 Prim 算法和 Kruskal 算法:
```c
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <limits.h>
#define MAX_VERTEX_NUM 6
#define MAX_EDGE_NUM 11
typedef struct {
char vex[MAX_VERTEX_NUM];
int edge[MAX_VERTEX_NUM][MAX_VERTEX_NUM];
int vexnum, edgenum;
} MGraph;
typedef struct {
int u, v, w;
} Edge;
bool visited[MAX_VERTEX_NUM];
void CreateMGraph(MGraph *G) {
G->vex[0] = 'A';
G->vex[1] = 'B';
G->vex[2] = 'C';
G->vex[3] = 'D';
G->vex[4] = 'E';
G->vex[5] = 'T';
G->edgenum = 11;
// 随机生成11条边,权值在[1,40]之间且不重复
G->edge[0][1] = G->edge[1][0] = 4;
G->edge[0][4] = G->edge[4][0] = 9;
G->edge[1][2] = G->edge[2][1] = 8;
G->edge[2][3] = G->edge[3][2] = 7;
G->edge[2][5] = G->edge[5][2] = 2;
G->edge[3][5] = G->edge[5][3] = 6;
G->edge[4][5] = G->edge[5][4] = 32;
G->edge[0][2] = G->edge[2][0] = 39;
G->edge[1][3] = G->edge[3][1] = 4;
G->edge[4][5] = G->edge[5][4] = 32;
}
void InitVisited() {
for (int i = 0; i < MAX_VERTEX_NUM; i++) {
visited[i] = false;
}
}
void Prim(MGraph G, int v0, int *path, int *cost) {
// 初始化路径和代价
for (int i = 0; i < MAX_VERTEX_NUM; i++) {
path[i] = v0;
cost[i] = G.edge[v0][i];
}
visited[v0] = true;
// 遍历剩下的n-1个顶点
for (int i = 1; i < MAX_VERTEX_NUM; i++) {
int min = INT_MAX, v = -1;
// 在未访问的顶点中找到距离集合最近的顶点
for (int j = 0; j < MAX_VERTEX_NUM; j++) {
if (!visited[j] && cost[j] < min) {
min = cost[j];
v = j;
}
}
visited[v] = true;
// 更新路径和代价
for (int j = 0; j < MAX_VERTEX_NUM; j++) {
if (!visited[j] && G.edge[v][j] < cost[j]) {
path[j] = v;
cost[j] = G.edge[v][j];
}
}
}
}
int Compare(const void *a, const void *b) {
Edge *ea = (Edge *) a;
Edge *eb = (Edge *) b;
return ea->w - eb->w;
}
int Find(int *parent, int i) {
while (parent[i] != i) {
i = parent[i];
}
return i;
}
void Union(int *parent, int i, int j) {
int pi = Find(parent, i);
int pj = Find(parent, j);
parent[pi] = pj;
}
void Kruskal(MGraph G, int *path, int *cost) {
Edge edges[MAX_EDGE_NUM];
int count = 0;
// 将边存入数组中
for (int i = 0; i < MAX_VERTEX_NUM; i++) {
for (int j = i + 1; j < MAX_VERTEX_NUM; j++) {
if (G.edge[i][j] != 0) {
edges[count].u = i;
edges[count].v = j;
edges[count].w = G.edge[i][j];
count++;
}
}
}
// 按照权值从小到大排序
qsort(edges, count, sizeof(Edge), Compare);
// 初始化并查集
int parent[MAX_VERTEX_NUM];
for (int i = 0; i < MAX_VERTEX_NUM; i++) {
parent[i] = i;
}
// 选择n-1条边
int i = 0, j = 0;
while (i < MAX_VERTEX_NUM - 1) {
int u = edges[j].u;
int v = edges[j].v;
int w = edges[j].w;
int pu = Find(parent, u);
int pv = Find(parent, v);
if (pu != pv) {
path[i] = u;
cost[i] = w;
Union(parent, pu, pv);
i++;
}
j++;
}
}
int main() {
MGraph G;
CreateMGraph(&G);
int path[MAX_VERTEX_NUM], cost[MAX_VERTEX_NUM];
InitVisited();
Prim(G, 0, path, cost);
printf("Prim算法:\n");
int sum = 0;
for (int i = 1; i < MAX_VERTEX_NUM; i++) {
printf("%c - %c (权值:%d)\n", G.vex[path[i]], G.vex[i], cost[i]);
sum += cost[i];
}
printf("最小生成树的代价为:%d\n", sum);
printf("Kruskal算法:\n");
Kruskal(G, path, cost);
sum = 0;
for (int i = 0; i < MAX_VERTEX_NUM - 1; i++) {
printf("%c - %c (权值:%d)\n", G.vex[path[i]], G.vex[path[i + 1]], cost[i]);
sum += cost[i];
}
printf("最小生成树的代价为:%d\n", sum);
return 0;
}
```
该代码中,我们先定义了邻接矩阵表示的无向网的数据结构,然后通过 CreateMGraph 函数随机生成符合要求的无向网。接着,我们分别实现了 Prim 算法和 Kruskal 算法,通过传入邻接矩阵表示的无向网,计算出最小生成树的路径和代价。最后,我们输出 Prim 算法和 Kruskal 算法得到的最小生成树,以及它们的代价。
阅读全文