请使用c语言编写一个代码以实现在n个城市n=5之间建设网络只需保证连通即可要求最经济的架设方法。1手动录入城市数nn=5及各城市之间的距离并将其储存起来。2存储结构需采用邻接表和邻接矩阵两种。3在代码编写时需要采用普利姆算法和克鲁斯卡尔算法两种。4输出所得的邻接表或邻接矩阵。5输出所得的最小生成树。
以下是使用C语言编写的代码,实现在n个城市之间建设网络的最经济方法,包括邻接表和邻接矩阵两种存储结构以及普利姆算法和克鲁斯卡尔算法两种最小生成树算法。
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
// 定义最大城市数量
#define MAX_CITY 10
// 邻接表节点结构
typedef struct Node {
int dest;
int weight;
struct Node* next;
} Node;
// 邻接表头结点结构
typedef struct HeadNode {
Node* head;
} HeadNode;
// 邻接矩阵结构
typedef struct {
int** matrix;
int num;
} Matrix;
// 创建邻接表头结点
HeadNode* createHeadNode() {
HeadNode* headNode = (HeadNode*)malloc(sizeof(HeadNode));
headNode->head = NULL;
return headNode;
}
// 创建邻接表节点
Node* createNode(int dest, int weight) {
Node* newNode = (Node*)malloc(sizeof(Node));
newNode->dest = dest;
newNode->weight = weight;
newNode->next = NULL;
return newNode;
}
// 添加邻接表节点到头结点
void addNode(HeadNode* headNode, int dest, int weight) {
Node* newNode = createNode(dest, weight);
newNode->next = headNode->head;
headNode->head = newNode;
}
// 创建邻接表
HeadNode** createAdjList(int num) {
HeadNode** adjList = (HeadNode**)malloc(num * sizeof(HeadNode*));
for (int i = 0; i < num; i++) {
adjList[i] = createHeadNode();
}
return adjList;
}
// 添加边到邻接表
void addEdgeToAdjList(HeadNode** adjList, int src, int dest, int weight) {
addNode(adjList[src], dest, weight);
addNode(adjList[dest], src, weight);
}
// 打印邻接表
void printAdjList(HeadNode** adjList, int num) {
for (int i = 0; i < num; i++) {
Node* currNode = adjList[i]->head;
printf("城市 %d 的邻接城市: ", i);
while (currNode != NULL) {
printf("%d ", currNode->dest);
currNode = currNode->next;
}
printf("\n");
}
}
// 创建邻接矩阵
Matrix* createAdjMatrix(int num) {
Matrix* adjMatrix = (Matrix*)malloc(sizeof(Matrix));
adjMatrix->matrix = (int**)malloc(num * sizeof(int*));
for (int i = 0; i < num; i++) {
adjMatrix->matrix[i] = (int*)calloc(num, sizeof(int));
}
adjMatrix->num = num;
return adjMatrix;
}
// 添加边到邻接矩阵
void addEdgeToAdjMatrix(Matrix* adjMatrix, int src, int dest, int weight) {
adjMatrix->matrix[src][dest] = weight;
adjMatrix->matrix[dest][src] = weight;
}
// 打印邻接矩阵
void printAdjMatrix(Matrix* adjMatrix) {
printf("邻接矩阵:\n");
for (int i = 0; i < adjMatrix->num; i++) {
for (int j = 0; j < adjMatrix->num; j++) {
printf("%d ", adjMatrix->matrix[i][j]);
}
printf("\n");
}
}
// 获取最小权重的边的起点
int getMinWeightEdge(int* weight, bool* visited, int num) {
int minWeight = INT_MAX;
int minIndex = -1;
for (int i = 0; i < num; i++) {
if (!visited[i] && weight[i] < minWeight) {
minWeight = weight[i];
minIndex = i;
}
}
return minIndex;
}
// Prim算法生成最小生成树
void primMST(HeadNode** adjList, int num) {
int* parent = (int*)malloc(num * sizeof(int));
int* weight = (int*)malloc(num * sizeof(int));
bool* visited = (bool*)calloc(num, sizeof(bool));
for (int i = 0; i < num; i++) {
weight[i] = INT_MAX;
}
weight[0] = 0;
parent[0] = -1;
for (int i = 0; i < num - 1; i++) {
int u = getMinWeightEdge(weight, visited, num);
visited[u] = true;
Node* currNode = adjList[u]->head;
while (currNode != NULL) {
int v = currNode->dest;
int w = currNode->weight;
if (!visited[v] && w < weight[v]) {
parent[v] = u;
weight[v] = w;
}
currNode = currNode->next;
}
}
printf("\nPrim算法生成的最小生成树:\n");
printf("边 权重\n");
for (int i = 1; i < num; i++) {
printf("%d - %d %d\n", parent[i], i, weight[i]);
}
}
// Kruskal算法生成最小生成树
typedef struct {
int src;
int dest;
int weight;
} Edge;
int compare(const void* a, const void* b) {
return ((Edge*)a)->weight - ((Edge*)b)->weight;
}
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(Edge* edges, int num, int edgeNum) {
int* parent = (int*)malloc(num * sizeof(int));
memset(parent, -1, num * sizeof(int));
qsort(edges, edgeNum, sizeof(Edge), compare);
printf("\nKruskal算法生成的最小生成树:\n");
printf("边 权重\n");
for (int i = 0; i < edgeNum; i++) {
int src = edges[i].src;
int dest = edges[i].dest;
int weight = edges[i].weight;
int x = find(parent, src);
int y = find(parent, dest);
if (x != y) {
printf("%d - %d %d\n", src, dest, weight);
unionSet(parent, x, y);
}
}
}
int main() {
int num;
printf("请输入城市数量(>= 5): ");
scanf("%d", &num);
if (num < 5) {
printf("城市数量不得小于5。\n");
return 0;
}
HeadNode** adjList = createAdjList(num);
Matrix* adjMatrix = createAdjMatrix(num);
Edge* edges = (Edge*)malloc((num * (num - 1) / 2) * sizeof(Edge));
int edgeNum = 0;
printf("请输入各城市之间的距离(用空格分隔):\n");
for (int i = 0; i < num; i++) {
for (int j = i + 1; j < num; j++) {
int weight;
printf("城市 %d 到城市 %d 的距离: ", i, j);
scanf("%d", &weight);
addEdgeToAdjList(adjList, i, j, weight);
addEdgeToAdjMatrix(adjMatrix, i, j, weight);
edges[edgeNum].src = i;
edges[edgeNum].dest = j;
edges[edgeNum].weight = weight;
edgeNum++;
}
}
printf("\n邻接表:\n");
printAdjList(adjList, num);
printf("\n邻接矩阵:\n");
printAdjMatrix(adjMatrix);
primMST(adjList, num);
kruskalMST(edges, num, edgeNum);
return 0;
}
使用此代码,首先手动录入城市数量n和各城市之间的距离,然后将其存储在邻接表和邻接矩阵中。然后,通过普利姆算法和克鲁斯卡尔算法生成最小生成树,并输出邻接表和邻接矩阵以及最小生成树的结果
原文地址: https://www.cveoy.top/t/topic/hGe3 著作权归作者所有。请勿转载和采集!