用C语言编程实现构建最小生成树的两种算法,可以动态输入,并详细解释代码

时间: 2023-12-21 09:03:57 浏览: 23
好的,下面我将介绍Prim算法和Kruskal算法,它们都是构建最小生成树的常用算法,同时也是经典的图论算法之一。 ### Prim算法 Prim算法是一种贪心算法,它的基本思想是从一个点开始,每次选择与已有的生成树中距离最近的点加入到生成树中。 下面是Prim算法的C语言代码实现: ```c #include <stdio.h> #include <limits.h> #define V 5 // 找到最小权值的顶点 int minKey(int key[], bool mstSet[]) { int min = INT_MAX, min_index; for (int v = 0; v < V; v++) if (mstSet[v] == false && key[v] < min) min = key[v], min_index = v; return min_index; } // 打印生成的最小生成树 void printMST(int parent[], int graph[V][V]) { printf("Edge \tWeight\n"); for (int i = 1; i < V; i++) printf("%d - %d \t%d \n", parent[i], i, graph[i][parent[i]]); } void primMST(int graph[V][V]) { int parent[V]; // 保存最小生成树 int key[V]; // 保存每个顶点的权值 bool mstSet[V]; // 记录每个顶点是否已经被访问过 // 初始化所有的key值为最大值 for (int i = 0; i < V; i++) key[i] = INT_MAX, mstSet[i] = false; key[0] = 0; parent[0] = -1; for (int count = 0; count < V - 1; count++) { int u = minKey(key, mstSet); mstSet[u] = true; for (int v = 0; v < V; v++) if (graph[u][v] && mstSet[v] == false && graph[u][v] < key[v]) parent[v] = u, key[v] = graph[u][v]; } printMST(parent, graph); } int main() { int graph[V][V] = { { 0, 2, 0, 6, 0 }, { 2, 0, 3, 8, 5 }, { 0, 3, 0, 0, 7 }, { 6, 8, 0, 0, 9 }, { 0, 5, 7, 9, 0 }, }; primMST(graph); return 0; } ``` 上述代码中,我们通过一个二维数组`graph`来表示一个图,其中`V`是顶点数。 在`primMST`函数中,我们首先初始化了所有的顶点的权值为最大值,然后将第一个点作为起点。 接下来,我们通过`minKey`函数找到与已有生成树中距离最近的顶点。然后将这个顶点加入到已有的生成树中,并更新所有未被访问过的顶点的权值。 最后,我们通过`printMST`函数打印出最小生成树的边和权值。 ### Kruskal算法 Kruskal算法也是一种贪心算法,它的基本思想是从边入手,每次选择一条权值最小且不会形成环的边加入到生成树中。 下面是Kruskal算法的C语言代码实现: ```c #include <stdio.h> #include <stdlib.h> #define V 5 #define E 7 struct Edge { int src, dest, weight; }; struct Graph { int V, E; struct Edge* edges; }; struct Graph* createGraph(int V, int E) { struct Graph* graph = (struct Graph*) malloc(sizeof(struct Graph)); graph->V = V; graph->E = E; graph->edges = (struct Edge*) malloc(graph->E * sizeof(struct Edge)); return graph; } // 找到顶点所在的集合 int find(int parent[], int i) { if (parent[i] == -1) return i; return find(parent, parent[i]); } // 合并两个集合 void Union(int parent[], int x, int y) { int xset = find(parent, x); int yset = find(parent, y); parent[xset] = yset; } // 比较边的权值 int myComp(const void* a, const void* b) { struct Edge* a1 = (struct Edge*) a; struct Edge* b1 = (struct Edge*) b; return a1->weight > b1->weight; } void kruskalMST(struct Graph* graph) { int* parent = (int*) malloc(graph->V * sizeof(int)); for (int i = 0; i < graph->V; i++) parent[i] = -1; qsort(graph->edges, graph->E, sizeof(graph->edges[0]), myComp); struct Edge result[graph->V]; int e = 0, i = 0; while (e < graph->V - 1 && i < graph->E) { struct Edge next_edge = graph->edges[i++]; int x = find(parent, next_edge.src); int y = find(parent, next_edge.dest); if (x != y) { result[e++] = next_edge; Union(parent, x, y); } } printf("Edge \tWeight\n"); for (i = 0; i < e; ++i) printf("%d - %d \t%d \n", result[i].src, result[i].dest, result[i].weight); return; } int main() { struct Graph* graph = createGraph(V, E); graph->edges[0].src = 0; graph->edges[0].dest = 1; graph->edges[0].weight = 2; graph->edges[1].src = 0; graph->edges[1].dest = 3; graph->edges[1].weight = 6; graph->edges[2].src = 1; graph->edges[2].dest = 3; graph->edges[2].weight = 8; graph->edges[3].src = 1; graph->edges[3].dest = 2; graph->edges[3].weight = 3; graph->edges[4].src = 1; graph->edges[4].dest = 4; graph->edges[4].weight = 5; graph->edges[5].src = 2; graph->edges[5].dest = 4; graph->edges[5].weight = 7; graph->edges[6].src = 3; graph->edges[6].dest = 4; graph->edges[6].weight = 9; kruskalMST(graph); return 0; } ``` 上述代码中,我们首先定义了一个`struct Edge`结构体来表示图中的边,以及一个`struct Graph`结构体来表示一个图。 在`kruskalMST`函数中,我们首先将所有的边按照权值进行排序,然后逐个选择边加入到生成树中,直到生成树的边数等于`V-1`为止。 在选择边的过程中,我们通过`find`函数找到每个顶点所在的集合,如果两个顶点不在同一个集合中,则将它们合并到一个集合中,并将这条边加入到生成树中。 最后,我们通过`result`数组打印出生成树的边和权值。

相关推荐

最新推荐

recommend-type

c语言编程的几种排序算法比较

排序算法是一种基本并且常用的算法。由于实际工作中处理的数量巨大,所以排序算法 对算法本身的速度要求很高。 而一般我们所谓的算法的性能主要是指算法的复杂度,一般用O方法来表示。在后面我将 给出详细的说明。
recommend-type

C语言实现哈夫曼树的构建

主要为大家详细介绍了C语言实现哈夫曼树的构建,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
recommend-type

最小生成树Prim算法朴素版 C语言实现

最小生成树Prim算法朴素版 C语言实现最小生成树Prim算法朴素版 C语言实现
recommend-type

C语言中计算二叉树的宽度的两种方式

主要介绍了C语言中计算二叉树的宽度的两种方式的相关资料,需要的朋友可以参考下
recommend-type

node-v4.1.0-linux-x64.tar.xz

Node.js,简称Node,是一个开源且跨平台的JavaScript运行时环境,它允许在浏览器外运行JavaScript代码。Node.js于2009年由Ryan Dahl创立,旨在创建高性能的Web服务器和网络应用程序。它基于Google Chrome的V8 JavaScript引擎,可以在Windows、Linux、Unix、Mac OS X等操作系统上运行。 Node.js的特点之一是事件驱动和非阻塞I/O模型,这使得它非常适合处理大量并发连接,从而在构建实时应用程序如在线游戏、聊天应用以及实时通讯服务时表现卓越。此外,Node.js使用了模块化的架构,通过npm(Node package manager,Node包管理器),社区成员可以共享和复用代码,极大地促进了Node.js生态系统的发展和扩张。 Node.js不仅用于服务器端开发。随着技术的发展,它也被用于构建工具链、开发桌面应用程序、物联网设备等。Node.js能够处理文件系统、操作数据库、处理网络请求等,因此,开发者可以用JavaScript编写全栈应用程序,这一点大大提高了开发效率和便捷性。 在实践中,许多大型企业和组织已经采用Node.js作为其Web应用程序的开发平台,如Netflix、PayPal和Walmart等。它们利用Node.js提高了应用性能,简化了开发流程,并且能更快地响应市场需求。
recommend-type

zigbee-cluster-library-specification

最新的zigbee-cluster-library-specification说明文档。
recommend-type

管理建模和仿真的文件

管理Boualem Benatallah引用此版本:布阿利姆·贝纳塔拉。管理建模和仿真。约瑟夫-傅立叶大学-格勒诺布尔第一大学,1996年。法语。NNT:电话:00345357HAL ID:电话:00345357https://theses.hal.science/tel-003453572008年12月9日提交HAL是一个多学科的开放存取档案馆,用于存放和传播科学研究论文,无论它们是否被公开。论文可以来自法国或国外的教学和研究机构,也可以来自公共或私人研究中心。L’archive ouverte pluridisciplinaire
recommend-type

实现实时数据湖架构:Kafka与Hive集成

![实现实时数据湖架构:Kafka与Hive集成](https://img-blog.csdnimg.cn/img_convert/10eb2e6972b3b6086286fc64c0b3ee41.jpeg) # 1. 实时数据湖架构概述** 实时数据湖是一种现代数据管理架构,它允许企业以低延迟的方式收集、存储和处理大量数据。与传统数据仓库不同,实时数据湖不依赖于预先定义的模式,而是采用灵活的架构,可以处理各种数据类型和格式。这种架构为企业提供了以下优势: - **实时洞察:**实时数据湖允许企业访问最新的数据,从而做出更明智的决策。 - **数据民主化:**实时数据湖使各种利益相关者都可
recommend-type

spring添加xml配置文件

1. 创建一个新的Spring配置文件,例如"applicationContext.xml"。 2. 在文件头部添加XML命名空间和schema定义,如下所示: ``` <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans
recommend-type

JSBSim Reference Manual

JSBSim参考手册,其中包含JSBSim简介,JSBSim配置文件xml的编写语法,编程手册以及一些应用实例等。其中有部分内容还没有写完,估计有生之年很难看到完整版了,但是内容还是很有参考价值的。