利用贪心法来设计并实现Prim算法。使用C语言,给出完整代码,给一组测试数据
时间: 2023-12-16 17:02:56 浏览: 74
以下是利用贪心法设计并实现Prim算法的C语言代码,其中使用了邻接矩阵来表示图:
```c
#include <stdio.h>
#include <stdlib.h>
#define INF 0x3f3f3f3f // 无限大
// 邻接矩阵结构体
typedef struct {
int **matrix; // 存储邻接矩阵
int vertex_num; // 顶点数
} AdjMatrix;
// 最小生成树结构体
typedef struct {
int *parent; // 存储每个节点的父节点
int *key; // 存储每个节点的关键字(到父节点的边权值)
} MST;
// 创建邻接矩阵
AdjMatrix *create_adj_matrix(int vertex_num) {
AdjMatrix *adj_matrix = (AdjMatrix *) malloc(sizeof(AdjMatrix));
adj_matrix->vertex_num = vertex_num;
adj_matrix->matrix = (int **) malloc(vertex_num * sizeof(int *));
for (int i = 0; i < vertex_num; i++) {
adj_matrix->matrix[i] = (int *) malloc(vertex_num * sizeof(int));
for (int j = 0; j < vertex_num; j++) {
adj_matrix->matrix[i][j] = INF;
}
}
return adj_matrix;
}
// 添加无向边
void add_undirected_edge(AdjMatrix *adj_matrix, int u, int v, int weight) {
adj_matrix->matrix[u][v] = weight;
adj_matrix->matrix[v][u] = weight;
}
// 释放邻接矩阵内存
void free_adj_matrix(AdjMatrix *adj_matrix) {
for (int i = 0; i < adj_matrix->vertex_num; i++) {
free(adj_matrix->matrix[i]);
}
free(adj_matrix->matrix);
free(adj_matrix);
}
// 创建最小生成树
MST *create_mst(int vertex_num) {
MST *mst = (MST *) malloc(sizeof(MST));
mst->parent = (int *) malloc(vertex_num * sizeof(int));
mst->key = (int *) malloc(vertex_num * sizeof(int));
for (int i = 0; i < vertex_num; i++) {
mst->parent[i] = -1;
mst->key[i] = INF;
}
return mst;
}
// 释放最小生成树内存
void free_mst(MST *mst) {
free(mst->parent);
free(mst->key);
free(mst);
}
// Prim算法
void prim(AdjMatrix *adj_matrix, MST *mst) {
int *visited = (int *) malloc(adj_matrix->vertex_num * sizeof(int)); // 存储每个节点是否被访问过
for (int i = 0; i < adj_matrix->vertex_num; i++) {
visited[i] = 0;
}
mst->parent[0] = -1; // 第一个节点作为根节点,没有父节点
mst->key[0] = 0; // 根节点的关键字为0
for (int i = 0; i < adj_matrix->vertex_num; i++) {
int u = -1;
for (int j = 0; j < adj_matrix->vertex_num; j++) { // 找到未被访问的关键字最小的节点
if (!visited[j] && (u == -1 || mst->key[j] < mst->key[u])) {
u = j;
}
}
visited[u] = 1; // 标记节点为已访问
for (int v = 0; v < adj_matrix->vertex_num; v++) { // 更新其它节点的关键字和父节点
if (!visited[v] && adj_matrix->matrix[u][v] < mst->key[v]) {
mst->parent[v] = u;
mst->key[v] = adj_matrix->matrix[u][v];
}
}
}
free(visited);
}
// 打印最小生成树
void print_mst(MST *mst) {
printf("Vertex\tParent\n");
for (int i = 1; i < mst->vertex_num; i++) {
printf("%d\t%d\n", i, mst->parent[i]);
}
}
int main() {
AdjMatrix *adj_matrix = create_adj_matrix(5); // 创建有5个节点的图
add_undirected_edge(adj_matrix, 0, 1, 2);
add_undirected_edge(adj_matrix, 0, 3, 1);
add_undirected_edge(adj_matrix, 1, 2, 3);
add_undirected_edge(adj_matrix, 1, 3, 4);
add_undirected_edge(adj_matrix, 1, 4, 5);
add_undirected_edge(adj_matrix, 2, 4, 6);
add_undirected_edge(adj_matrix, 3, 4, 7);
MST *mst = create_mst(5); // 创建有5个节点的最小生成树
prim(adj_matrix, mst); // 计算最小生成树
print_mst(mst); // 打印最小生成树
free_adj_matrix(adj_matrix); // 释放邻接矩阵内存
free_mst(mst); // 释放最小生成树内存
return 0;
}
```
下面是一组测试数据,对应上述代码中的图:
```
Vertex Parent
1 0
2 1
3 0
4 1
```
阅读全文