以下是一个使用C语言实现的最小生成树算法的示例代码。其中使用了邻接表和邻接矩阵两种存储结构,并分别采用了普利姆算法和克鲁斯卡尔算法来构建最小生成树。

#include <stdio.h>
#include <stdlib.h>
#include <limits.h>

// 定义最大城市数量
#define MAX_CITIES 100

// 邻接表中的链表节点
typedef struct Node {
    int city;
    int distance;
    struct Node* next;
} Node;

// 邻接表
typedef struct {
    Node* head;
} AdjList[MAX_CITIES];

// 邻接矩阵
typedef int AdjMatrix[MAX_CITIES][MAX_CITIES];

// 普利姆算法
void prim(int n, AdjList adjList, AdjMatrix adjMatrix) {
    int selected[MAX_CITIES]; // 记录已选中的城市
    int minDistance[MAX_CITIES]; // 记录到每个城市的最小距离
    int parent[MAX_CITIES]; // 记录每个城市的父节点
    int totalDistance = 0; // 记录最小生成树的总距离

    // 初始化数据
    for (int i = 0; i < n; i++) {
        selected[i] = 0;
        minDistance[i] = INT_MAX;
        parent[i] = -1;
    }

    // 从第一个城市开始构建最小生成树
    minDistance[0] = 0;

    for (int i = 0; i < n; i++) {
        int minIndex = -1;
        int min = INT_MAX;

        // 选取最小距离的城市
        for (int j = 0; j < n; j++) {
            if (!selected[j] && minDistance[j] < min) {
                min = minDistance[j];
                minIndex = j;
            }
        }

        selected[minIndex] = 1; // 将城市标记为已选中

        // 更新其他城市的最小距离和父节点信息
        for (Node* node = adjList[minIndex].head; node != NULL; node = node->next) {
            int city = node->city;
            int distance = node->distance;
            if (!selected[city] && distance < minDistance[city]) {
                minDistance[city] = distance;
                parent[city] = minIndex;
            }
        }
    }

    // 输出最小生成树的节点及权值
    printf("Prim Algorithm:\n");
    for (int i = 1; i < n; i++) {
        printf("Edge: %d - %d, Distance: %d\n", parent[i], i, adjMatrix[i][parent[i]]);
        totalDistance += adjMatrix[i][parent[i]];
    }
    printf("Total Distance: %d\n", totalDistance);
}

// 克鲁斯卡尔算法
void kruskal(int n, AdjList adjList, AdjMatrix adjMatrix) {
    int parent[MAX_CITIES]; // 记录每个城市的父节点
    int totalDistance = 0; // 记录最小生成树的总距离

    // 初始化父节点信息
    for (int i = 0; i < n; i++) {
        parent[i] = -1;
    }

    // 构建边集合
    typedef struct {
        int city1;
        int city2;
        int distance;
    } Edge;

    Edge edges[MAX_CITIES * MAX_CITIES];
    int numEdges = 0;

    for (int i = 0; i < n; i++) {
        for (Node* node = adjList[i].head; node != NULL; node = node->next) {
            if (i < node->city) {
                edges[numEdges].city1 = i;
                edges[numEdges].city2 = node->city;
                edges[numEdges].distance = node->distance;
                numEdges++;
            }
        }
    }

    // 对边集合按照距离进行排序
    for (int i = 0; i < numEdges - 1; i++) {
        for (int j = 0; j < numEdges - i - 1; j++) {
            if (edges[j].distance > edges[j + 1].distance) {
                Edge temp = edges[j];
                edges[j] = edges[j + 1];
                edges[j + 1] = temp;
            }
        }
    }

    // 使用并查集判断边是否会形成环路
    int numSelectedEdges = 0;
    int index = 0;

    while (numSelectedEdges < n - 1 && index < numEdges) {
        Edge edge = edges[index++];
        int city1 = edge.city1;
        int city2 = edge.city2;

        while (parent[city1] != -1) {
            city1 = parent[city1];
        }
        while (parent[city2] != -1) {
            city2 = parent[city2];
        }

        if (city1 != city2) {
            parent[city2] = city1;
            printf("Edge: %d - %d, Distance: %d\n", edge.city1, edge.city2, edge.distance);
            totalDistance += edge.distance;
            numSelectedEdges++;
        }
    }

    printf("Total Distance: %d\n", totalDistance);
}

// 创建邻接表和邻接矩阵
void createGraph(int n, AdjList adjList, AdjMatrix adjMatrix) {
    // 初始化邻接表
    for (int i = 0; i < n; i++) {
        adjList[i].head = NULL;
    }

    // 手动录入城市之间的距离并将其存储起来
    for (int i = 0; i < n; i++) {
        for (int j = i + 1; j < n; j++) {
            int distance;
            printf("Enter distance between city %d and city %d: ", i, j);
            scanf("%d", &distance);

            // 更新邻接表
            Node* newNode = (Node*)malloc(sizeof(Node));
            newNode->city = j;
            newNode->distance = distance;
            newNode->next = adjList[i].head;
            adjList[i].head = newNode;

            newNode = (Node*)malloc(sizeof(Node));
            newNode->city = i;
            newNode->distance = distance;
            newNode->next = adjList[j].head;
            adjList[j].head = newNode;

            // 更新邻接矩阵
            adjMatrix[i][j] = distance;
            adjMatrix[j][i] = distance;
        }
    }
}

// 输出邻接表
void printAdjList(int n, AdjList adjList) {
    printf("Adjacency List:\n");
    for (int i = 0; i < n; i++) {
        printf("City %d:", i);
        for (Node* node = adjList[i].head; node != NULL; node = node->next) {
            printf(" -> City %d, Distance %d", node->city, node->distance);
        }
        printf("\n");
    }
}

// 输出邻接矩阵
void printAdjMatrix(int n, AdjMatrix adjMatrix) {
    printf("Adjacency Matrix:\n");
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            printf("%d\t", adjMatrix[i][j]);
        }
        printf("\n");
    }
}

int main() {
    int n;

    printf("Enter the number of cities (n >= 5): ");
    scanf("%d", &n);

    if (n < 5) {
        printf("Invalid number of cities.\n");
        return 0;
    }

    AdjList adjList;
    AdjMatrix adjMatrix;

    createGraph(n, adjList, adjMatrix);
    printAdjList(n, adjList);
    printAdjMatrix(n, adjMatrix);

    prim(n, adjList, adjMatrix);
    kruskal(n, adjList, adjMatrix);

    return 0;
}

主要函数说明:

  • prim函数实现了普利姆算法,通过循环选择最小距离的城市,并更新其他城市的最小距离和父节点信息。最后输出最小生成树的节点及权值。
  • kruskal函数实现了克鲁斯卡尔算法,首先构建边集合并按照距离进行排序,然后使用并查集判断边是否会形成环路。最后输出最小生成树的节点及权值。
  • createGraph函数用于手动录入城市之间的距离,并更新邻接表和邻接矩阵。
  • printAdjList函数用于输出邻接表。
  • printAdjMatrix函数用于输出邻接矩阵。
  • main函数为程序的入口,首先获取城市数量,然后创建邻接表和邻接矩阵,接着调用打印函数和最小生成树算法函数
用c语言编写一个代码以实现在n个城市n=5之间建设网络只需保证连通即可要求最经济的架设方法。1手动录入城市数nn=5及各城市之间的距离并将其储存起来。2存储结构需采用邻接表和邻接矩阵两种。3在代码编写时需要采用普利姆算法和克鲁斯卡尔算法两种。4输出所得的邻接表或邻接矩阵。5输出所得的最小生成树需要包括节点及权值。并对主要函数进行说明

原文地址: https://www.cveoy.top/t/topic/hIBa 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录