任意给定一个带权图,求其最小生成树。使用避圈法或破圈法,用c语言编写
时间: 2024-03-12 14:45:14 浏览: 85
以下是使用Prim算法求带权图最小生成树的C语言实现:
```
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
// 定义边的结构体
typedef struct edge {
int to; // 终点
int weight; // 权重
struct edge *next; // 指向下一条边的指针
} Edge;
// 定义图的结构体
typedef struct graph {
int n; // 节点数
Edge **adjList; // 邻接表数组
} Graph;
// 创建边
Edge *createEdge(int to, int weight) {
Edge *edge = (Edge *) malloc(sizeof(Edge));
edge->to = to;
edge->weight = weight;
edge->next = NULL;
return edge;
}
// 创建图
Graph *createGraph(int n) {
Graph *graph = (Graph *) malloc(sizeof(Graph));
graph->n = n;
graph->adjList = (Edge **) malloc(n * sizeof(Edge *));
for (int i = 0; i < n; i++) {
graph->adjList[i] = NULL;
}
return graph;
}
// 添加边
void addEdge(Graph *graph, int from, int to, int weight) {
Edge *edge = createEdge(to, weight);
edge->next = graph->adjList[from];
graph->adjList[from] = edge;
}
// 释放图的内存
void freeGraph(Graph *graph) {
for (int i = 0; i < graph->n; i++) {
Edge *edge = graph->adjList[i];
while (edge != NULL) {
Edge *temp = edge;
edge = edge->next;
free(temp);
}
}
free(graph->adjList);
free(graph);
}
// 使用Prim算法求最小生成树
void prim(Graph *graph) {
int *visited = (int *) malloc(graph->n * sizeof(int)); // 标记节点是否已经加入生成树
int *dist = (int *) malloc(graph->n * sizeof(int)); // 存放节点到生成树的最短距离
int *parent = (int *) malloc(graph->n * sizeof(int)); // 存放节点的父节点
for (int i = 0; i < graph->n; i++) {
visited[i] = 0;
dist[i] = INT_MAX;
parent[i] = -1;
}
dist[0] = 0; // 将起点加入生成树
for (int i = 0; i < graph->n - 1; i++) {
// 找到未加入生成树的节点中到生成树距离最短的节点
int minDist = INT_MAX;
int minIndex = -1;
for (int j = 0; j < graph->n; j++) {
if (!visited[j] && dist[j] < minDist) {
minDist = dist[j];
minIndex = j;
}
}
visited[minIndex] = 1; // 将该节点加入生成树
// 更新与该节点相邻的节点到生成树的最短距离
Edge *edge = graph->adjList[minIndex];
while (edge != NULL) {
int to = edge->to;
int weight = edge->weight;
if (!visited[to] && weight < dist[to]) {
dist[to] = weight;
parent[to] = minIndex;
}
edge = edge->next;
}
}
// 输出最小生成树的边
printf("最小生成树的边为:\n");
for (int i = 1; i < graph->n; i++) {
printf("(%d, %d, %d)\n", parent[i], i, dist[i]);
}
// 释放内存
free(visited);
free(dist);
free(parent);
}
int main() {
int n = 5; // 图的节点数
Graph *graph = createGraph(n);
addEdge(graph, 0, 1, 2);
addEdge(graph, 0, 3, 6);
addEdge(graph, 1, 2, 3);
addEdge(graph, 1, 3, 8);
addEdge(graph, 1, 4, 5);
addEdge(graph, 2, 4, 7);
addEdge(graph, 3, 4, 9);
prim(graph);
// 释放内存
freeGraph(graph);
return 0;
}
```
上述代码中,我们使用了Prim算法来求最小生成树。首先将起点加入生成树,然后每次找到未加入生成树的节点中到生成树距离最短的节点,将该节点加入生成树,并更新与该节点相邻的节点到生成树的最短距离。最终得到的结果是最小生成树的所有边。
阅读全文