【c语言】Prim算法与Kruskal算法的比较与实现,寻找最小支撑树(生成树)

  • 实验目的

Learn and understand the Prim algorithm, Kruskal algorithm through programming, and implement the prim algorithm by using the cocycle method. Compare and distinguish the application scope of different algorithms in learning

  • 实验内容

Prim algorithm, Kruskal algorithm are implemented in the computer by programming in C-language to find the Minimum spanning tree. The prim algorithm tries to use the cocycle method.

  • 使用环境

Win 11 & visual studio code 2022

  • 算法介绍

  • 调试过程

  1. 调试代码

The program takes the file as the input, and the file content is

Code:

#include <stdio.h>
#include <stdlib.h>
#define V 4 // V是图的顶点数
struct graph
{
    char vert1;
    char vert2;
    int weight;
};
typedef struct graph graph;
graph edge[10];
int n = 0;
int MOG[10][10];
graph minitree[V - 1]; // 最小树的边是顶点数减一

void matrify(int m) // 转换为矩阵
{
    int i, x, y;
    for (i = 0; i < m; i++)
    {
        x = edge[i].vert1 - 65;
        y = edge[i].vert2 - 65;
        MOG[x][y] = MOG[y][x] = edge[i].weight;
    }
}
void showM()
{
    int i, j;
    for (i = 0; i < V; i++) // 打印权重矩阵
    {
        for (j = 0; j < V; j++)
        {
            printf("%d ", MOG[i][j]);
        }
        printf("\n");
    }
}
void PRIM()
{
    int i, j, minw, temp;
    int a, b, s = 0, M = V - 2;
    while (M > 0)
    {
        minw = MOG[0][1];
        for (i = 0; i < V - 1; i++) // 找最小权重
        {
            for (j = i + 1; j < V; j++) // 遍历一半的矩阵即可
            {
                temp = MOG[i][j];
                if (temp < minw && temp != 0)
                {
                    minw = temp;
                    a = i;
                    b = j;
                }
            }
        }
        minitree[s].vert1 = (a + 65);
        minitree[s].vert2 = (b + 65);
        minitree[s].weight = minw;
        s++;
        for (i = 0; i < V; i++) // 合并行
        {
            if (MOG[a][i] != 0 && MOG[b][i] != 0)
                MOG[a][i] = (MOG[a][i] < MOG[b][i]) ? MOG[a][i] : MOG[b][i];
            else
                MOG[a][i] = MOG[a][i] + MOG[b][i];
        }
        for (j = 0; j < V; j++) // 合并列
        {
            if (MOG[j][a] != 0 && MOG[j][b] != 0)
                MOG[j][a] = (MOG[j][a] < MOG[j][b]) ? MOG[j][a] : MOG[j][b];
            else
                MOG[j][a] = MOG[j][a] + MOG[j][b];
        }
        for (i = 0; i < V; i++)
        {
            MOG[b][i] = MOG[i][b] = 0;
            MOG[i][i] = 0; // 对角线为0
        }
        M--;
        printf("Matrix of weights:\n");
        showM(); // 展示每一步
    }
    matrify(n);
    for (i = 0; i < (V - 2); i++)
    {
        a = minitree[i].vert1 - 65;
        b = minitree[i].vert2 - 65;
        MOG[a][b] = MOG[b][a] = 0;
    }
    minw = MOG[0][1];
    for (i = 0; i < V - 1; i++)
    {
        for (j = i + 1; j < V; j++)
        {
            temp = MOG[i][j];
            if (temp < minw && temp != 0)
            {
                minw = temp;
                a = i;
                b = j;
            }
        }
    }
    minitree[s].vert1 = (a + 65);
    minitree[s].vert2 = (b + 65);
    minitree[s].weight = minw;
}

int main()
{
    int i, j;
    FILE *fp;
    fp = fopen("D:/work code/C Storageroom/discrete/graph01.txt", "r"); // 只读的方式打开文件
    if (fp == NULL)                                                     // 判断文件是否正常打开
    {
        printf("can not open the file\n");
        exit(0);
    }
    while (!feof(fp)) // 从文件中读入数据
    {
        edge[n].vert1 = fgetc(fp);
        edge[n].vert2 = fgetc(fp);
        fscanf(fp, "%d", &edge[n].weight);
        n++;
    }
    fclose(fp);             // 关闭文件
    for (i = 0; i < n; i++) // 打印数据
        printf("%c %c %d\n", edge[i].vert1, edge[i].vert2, edge[i].weight);
    matrify(n);
    printf("the matrix of weights\n");
    showM();
    PRIM();
    printf("output:\n");
    for (i = 0; i < (V - 1); i++) // 打印数据
        printf("%c %c %d\n", minitree[i].vert1, minitree[i].vert2, minitree[i].weight);
    return 0;
}

运行结果

  • 总结

The spanning tree of an undirected graph is to select some edges from the edge set of the graph, so that these edges form a connected acyclic graph, that is, a tree. If a weight is added to each edge, the spanning tree with the smallest sum of weights in all spanning trees is called the minimum spanning tree. Prim algorithm and Kruskal algorithm are algorithms that use MST properties to construct the minimum spanning tree. The experimental graph is stored in the form of adjacency matrix. Sometimes the results of Prim algorithm are not unique.

  • 参考文献

[1]谭浩强,C 程序设计[M] (第四版).北京:清华大学出版社,2010年6月(中国高等院校计算机基础教育课程体系规划教材)

[2]谭浩强, C 程序设计( 第四版 )学习辅导 ,北京:清华大学出版社,2010年7月(中国高等院校计算机基础教育课程体系规划教材)

[3]C Primer Plus (第6版)中文版,Stephen Prata 著;姜佑译 ——北京 :人名邮电出版社,2019.11

  • 11
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Prim算法实现最小生成树C语言代码: ``` #include <stdio.h> #include <stdlib.h> #include <limits.h> #define MAX_VERTICES 1000 typedef struct { int x; int y; } Point; Point points[MAX_VERTICES]; int graph[MAX_VERTICES][MAX_VERTICES]; int visited[MAX_VERTICES]; int parent[MAX_VERTICES]; int dist[MAX_VERTICES]; int main() { int n, m; scanf("%d%d", &n, &m); for (int i = 0; i < n; i++) { scanf("%d%d", &points[i].x, &points[i].y); visited[i] = 0; parent[i] = -1; dist[i] = INT_MAX; for (int j = 0; j < n; j++) { graph[i][j] = 0; } } for (int i = 0; i < m; i++) { int u, v; scanf("%d%d", &u, &v); u--; v--; int dx = points[u].x - points[v].x; int dy = points[u].y - points[v].y; int w = dx * dx + dy * dy; graph[u][v] = w; graph[v][u] = w; } int start = 0; dist[start] = 0; for (int i = 0; i < n; i++) { int u = -1; for (int j = 0; j < n; j++) { if (!visited[j] && (u == -1 || dist[j] < dist[u])) { u = j; } } visited[u] = 1; for (int v = 0; v < n; v++) { if (graph[u][v] > 0 && graph[u][v] < dist[v]) { parent[v] = u; dist[v] = graph[u][v]; } } } int total_weight = 0; for (int i = 0; i < n; i++) { if (parent[i] != -1) { total_weight += graph[i][parent[i]]; } } printf("%d\n", total_weight); return 0; } ``` Kruskal算法实现最小生成树C语言代码: ``` #include <stdio.h> #include <stdlib.h> #include <limits.h> #define MAX_VERTICES 1000 #define MAX_EDGES 1000000 typedef struct { int x; int y; } Point; Point points[MAX_VERTICES]; int parent[MAX_VERTICES]; int rank[MAX_VERTICES]; int edges[MAX_EDGES][3]; int find(int x) { if (parent[x] != x) { parent[x] = find(parent[x]); } return parent[x]; } void unite(int x, int y) { int px = find(x); int py = find(y); if (rank[px] < rank[py]) { parent[px] = py; } else { parent[py] = px; if (rank[px] == rank[py]) { rank[px]++; } } } int compare_edge(const void *p, const void *q) { int *a = (int*) p; int *b = (int*) q; return a[2] - b[2]; } int main() { int n, m; scanf("%d%d", &n, &m); for (int i = 0; i < n; i++) { scanf("%d%d", &points[i].x, &points[i].y); parent[i] = i; rank[i] = 0; } for (int i = 0; i < m; i++) { int u, v; scanf("%d%d", &u, &v); u--; v--; int dx = points[u].x - points[v].x; int dy = points[u].y - points[v].y; int w = dx * dx + dy * dy; edges[i][0] = u; edges[i][1] = v; edges[i][2] = w; } qsort(edges, m, sizeof(int[3]), compare_edge); int total_weight = 0; for (int i = 0; i < m; i++) { int u = edges[i][0]; int v = edges[i][1]; int w = edges[i][2]; if (find(u) != find(v)) { unite(u, v); total_weight += w; } } printf("%d\n", total_weight); return 0; } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值