c语言实现最小生成树算法
C语言实现最小生成树构造算法

C语⾔实现最⼩⽣成树构造算法最⼩⽣成树最⼩⽣成树(minimum spanning tree)是由n个顶点,n-1条边,将⼀个连通图连接起来,且使权值最⼩的结构。
最⼩⽣成树可以⽤Prim(普⾥姆)算法或kruskal(克鲁斯卡尔)算法求出。
我们将以下⾯的带权连通图为例讲解这两种算法的实现:注:由于测试输⼊数据较多,程序可以采⽤⽂件输⼊Prim(普⾥姆)算法时间复杂度:O(N^2)(N为顶点数)prim算法⼜称“加点法”,⽤于边数较多的带权⽆向连通图⽅法:每次找与之连线权值最⼩的顶点,将该点加⼊最⼩⽣成树集合中注意:相同权值任选其中⼀个即可,但是不允许出现闭合回路的情况。
代码部分通过以下步骤可以得到最⼩⽣成树:1.初始化:lowcost[i]:表⽰以i为终点的边的最⼩权值,当lowcost[i]=0表⽰i点加⼊了MST。
mst[i]:表⽰对应lowcost[i]的起点,当mst[i]=0表⽰起点i加⼊MST。
由于我们规定最开始的顶点是1,所以lowcost[1]=0,MST[1]=0。
即只需要对2~n进⾏初始化即可。
#define MAX 100#define MAXCOST 0x7fffffffint graph[MAX][MAX];void prim(int graph[][MAX], int n){int lowcost[MAX];int mst[MAX];int i, j, min, minid, sum = 0;for (i = 2; i <= n; i++){lowcost[i] = graph[1][i];//lowcost存放顶点1可达点的路径长度mst[i] = 1;//初始化以1位起始点}mst[1] = 0;2.查找最⼩权值及路径更新定义⼀个最⼩权值min和⼀个最⼩顶点ID minid,通过循环查找出min和minid,另外由于规定了某⼀顶点如果被连⼊,则lowcost[i]=0,所以不需要担⼼重复点问题。
1.6最小生成树及其算法

如果生成树T *的权 w(T * ) 是 G 的所有生成树的权中最 小者,则称 T * 是 G 的最小生成树,简称为最小树,即
w(T * ) min{w(T )},式中取遍 G 的所有生成树T .
T
介绍最小树的两种算法: Kruskal算法(或避圈法)和破圈法.
A. Kruskal算法(或避圈法)
b)广探法 例用广探法求出下图10的一棵生成树 步骤如下: i) 在点集V中任取一点u, 给u以标号0. ii) 令所有标号i的点集为 Vi,检查[Vi,V\Vi]中的边端点 是否均已标号. 对所有未标 号之点均标以i+1,记下这些 边. iii) 对标号i+1的点重复步 步骤ii),直到全部点得到 标号为止.
步 骤
u
L( b)
L( c)
L( d)
L( e)
L(f)
L( g)
e
V
T0
C(T 0)
1 2 3 4
a b e c
4 - - -
15 9 5 -
32 25
7 7 - -
28 28 28 (a, b) (a, e)
{a} {a, b} {a, b, e}
{(a, b)} {(a, b), (a, e)} {(a, b), (a, e), (c, e)}
(5)T T {e k }, k,t t 1, k k 1, 转( ) 3
例5.3 用Kruskal算法求下图的最小生成树。
解:将图的边按照权值从小到大进行排列,列 出下表
边 (a, b) (c, e) (a, e) (b, c) (d, g) (a, c)
3) 当第2)步不能继续执行时,则停止. 定理5.3 由Kruskal算法构作的任何生成树都是 最小树。
实验5最小生成树算法的设计与实现(报告)

实验5 最小生成树算法的设计与实现一、实验目的1、根据算法设计需要, 掌握连通图的灵活表示方法;2、掌握最小生成树算法,如Prim、Kruskal算法;3、基本掌握贪心算法的一般设计方法;4、进一步掌握集合的表示与操作算法的应用。
二、实验内容1、认真阅读算法设计教材和数据结构教材内容, 熟习连通图的不同表示方法和最小生成树算法;2、设计Kruskal算法实验程序。
有n个城市可以用(n-1)条路将它们连通,求最小总路程的和。
设计测试问题,修改并调试程序, 输出最小生成树的各条边, 直至正确为止。
三、Kruskal算法的原理方法边权排序:1 3 14 6 23 6 41 4 52 3 53 4 52 5 61 2 63 5 65 6 61. 初始化时:属于最小生成树的顶点U={}不属于最小生成树的顶点V={1,2,3,4,5,6}2. 根据边权排序,选出还没有连接并且权最小的边(1 3 1),属于最小生成树的顶点U={1,3},不属于最小生成树的顶点V={2,4,5,6}3. 根据边权排序,选出还没有连接并且权最小的边(4 6 2),属于最小生成树的顶点U={{1,3},{4,6}}(还没有合在一起,有两颗子树),不属于最小生成树的顶点V={2,5}4. 根据边权排序,选出还没有连接并且权最小的边(3 6 4),属于最小生成树的顶点U={1,3,4,6}(合在一起),不属于最小生成树的顶点V={2,5}5. 根据边权排序,选出还没有连接并且权最小的边(3 6 4),属于最小生成树的顶点U={1,2,3,4,6},,不属于最小生成树的顶点V={5}6. 根据边权排序,选出还没有连接并且权最小的边(3 6 4),属于最小生成树的顶点U={1,2,3,4,5,6}此时,最小生成树已完成四、实验程序的功能模块功能模块:bool cmp(Edge a,Edge b); //定义比较方法x);//在并查集森林中找到x的祖先int g etfa(intint s ame(int x,int y); //判断祖先是否是同一个,即是否联通 void merge(int x,int y); //合并子树,即联通两子树sort(e+1,e+m+1,cmp); //对边按边权进行升序排序详细代码:#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>#define M AXN_E 100000#define M AXN_V 100000using namespace std;struct Edge{int f m,to,dist;//边的起始顶点,边的到达顶点,边权}e[MAXN_E];int f a[MAXN_V],n,m; //顶点数组,顶点总数,边总数 //定义比较,只是边权比较bool cmp(Edge a,Edge b){return a.dist < b.dist;}//查找x的祖先是在并查集森林中找到x的祖先x){//getfaint g etfa(intreturn fa[x];if(fa[x]==x)else r eturn fa[x] = getfa(fa[x]);}//判断祖先是否是同一个,即是否联通int s ame(int x,int y){return getfa(x)==getfa(y);}//合并两棵树void merge(int x,int y){int f ax=getfa(x),fay=getfa(y);fa[fax]=fay;}int m ain(){int i;cout<<"请输入顶点数目和边数目:"<<endl;cin>>n>>m;//n为点数,m为边数//输出顶点信息cout<<"各个顶点值依次为:"<<endl;for(i=0;i<n;i++){fa[i]=i;if(i!=0)cout<<fa[i]<<" ";}cout<<endl;cout<<"请输入边的信息(例子:1 4 5 从顶点1到顶点4的边权为5)"<<endl;for(i=1;i<=m;i++)用边集数组存放边,方便排序和调用 cin>>e[i].fm>>e[i].to>>e[i].dist;//sort(e+1,e+m+1,cmp); //对边按边权进行升序排序表示目前的点共存在于多少个集合中,初始情况是每 int r st=n,ans=0;//rst个点都在不同的集合中for(i=1;i<=m && rst>1;i++){int x=e[i].fm,y=e[i].to;函数是查询两个点是否在同一集合中 if(same(x,y))continue;//sameelse{函数用来将两个点合并到同一集合中 merge(x,y);//mergerst--;//每次将两个不同集合中的点合并,都将使rst值减1这条边是最小生成树中的边,将答案加上边权 ans+=e[i].dist;//}}cout<<ans;return 0;}五、测试数据和相应的最小生成树Input:6 101 2 61 3 11 4 52 3 52 5 63 4 53 5 63 6 44 6 25 6 6Putout:18生成树为:七、思考题1、微软面试题一个大院子里住了50户人家,每家都养了一条狗,有一天他们接到通知说院子里有狗生病了,并要求所有主人在发现自己家狗生病的当天就要把狗枪杀掉。
C语言常用算法总结

C语言常用算法总结1、冒泡排序算法:冒泡排序是一种简单的排序算法,它重复地遍历要排序的序列,一次比较两个相邻的元素如果他们的顺序错误就把他们交换过来。
时间复杂度为O(n^2)。
2、快速排序算法:快速排序是一种基于分治的排序算法,通过递归的方式将数组划分为两个子数组,然后对子数组进行排序最后将排好序的子数组合并起来。
时间复杂度为O(nlogn)。
3、插入排序算法:插入排序是一种简单直观的排序算法,通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描找到相应位置并插入。
时间复杂度为O(n^2)。
4、选择排序算法:选择排序是一种简单的排序算法,每次循环选择未排序部分的最小元素,并放置在已排序部分的末尾。
时间复杂度为O(n^2)。
5、归并排序算法:归并排序是一种稳定的排序算法,基于分治思想,将数组递归地分为两个子数组,将子数组排序后再进行合并最终得到有序的数组。
时间复杂度为O(nlogn)。
6、堆排序算法:堆排序是一种基于完全二叉堆的排序算法,通过构建最大堆或最小堆,然后依次将堆顶元素与末尾元素交换再调整堆,得到有序的数组。
时间复杂度为O(nlogn)。
7、二分查找算法:二分查找是一种在有序数组中查找目标元素的算法,每次将待查找范围缩小一半,直到找到目标元素或范围为空。
时间复杂度为O(logn)。
8、KMP算法:KMP算法是一种字符串匹配算法,通过利用模式字符串的自重复性,避免不必要的比较提高匹配效率。
时间复杂度为O(m+n),其中m为文本串长度,n为模式串长度。
9、动态规划算法:动态规划是一种通过将问题分解为子问题,并通过组合子问题的解来求解原问题的方法。
动态规划算法通常使用内存空间来存储中间结果,从而避免重复计算。
时间复杂度取决于问题规模。
10、贪心算法:贪心算法是一种通过选择局部最优解来构建全局最优解的算法并以此构建最终解。
时间复杂度取决于问题规模。
11、最短路径算法:最短路径算法用于求解图中两个节点之间的最短路径,常见的算法包括Dijkstra算法和Floyd-Warshall算法。
最小生成树例题贪心算法c语言算法与设计

最小生成树例题贪心算法c语言算法与设计题目:最小生成树例题——贪心算法在C语言算法与设计中的应用引言:在算法和数据结构的学习过程中,贪心算法是一种常见且重要的思想。
它通过每一步局部最优的选择来构建整体最优解。
最小生成树问题是贪心算法的经典例题之一,而在C语言算法与设计中,理解并应用贪心算法是非常必要的。
本文将围绕最小生成树例题展开,探讨贪心算法在C语言算法与设计中的应用。
一、最小生成树(Minimum Spanning Tree)的定义与理解1.1 概念解析最小生成树是图论中的一个概念,它指的是在连通图中找到一棵树,使得这棵树的所有边的权值之和最小。
最小生成树常应用于优化问题,如电缆布线以及城市间道路建设等。
1.2 算法应用最小生成树常用于解决具有边权的连通图问题。
在实际应用中,我们通常使用Kruskal算法或Prim算法来求解最小生成树。
二、Kruskal算法详解2.1 思想描述Kruskal算法是一种基于贪心思想的算法,其主要思路是依次选择边权最小且不形成回路的边,直到生成最小生成树。
2.2 具体步骤(1)将图中的所有边按照权值从小到大进行排序;(2)从权值最小的边开始,如果该边的两个端点不在同一个连通分量中,则将其加入最小生成树,并合并两个连通分量;(3)重复步骤(2),直到最小生成树包含图中的所有节点。
2.3 例子分析以以下图为例说明Kruskal算法的应用过程:```(图1)```(1)将图中的边按照权值从小到大排序得到如下顺序:```A-B: 1E-F: 1B-C: 2E-G: 2C-D: 3D-F: 3F-G: 4```(2)选取权值最小的边A-B,并将A和B加入最小生成树。
此时连通分量为{A}和{B}。
```(图2)```(3)选取权值次小的边E-F,可以将其加入最小生成树,同时连通分量中加入F。
此时连通分量为{A},{B}和{F}。
```(图3)```(4)依次选择权值较小的边,直到最小生成树中包含图中的所有节点。
prim算法c语言

prim算法c语言什么是Prim算法?Prim算法,也叫普里姆算法,是一种用于求解最小生成树的贪心算法。
最小生成树是指在一个无向连通图中,连接所有节点且边权值之和最小的树。
Prim算法的基本思想是从一个起始节点开始,每次选择与当前已经构建好的部分形成的子图相连的、权值最小的边所连接的节点,并将该节点加入到已经构建好的部分中。
直到所有节点都被加入到已经构建好的部分中,此时得到了一棵最小生成树。
Prim算法步骤1. 选定一个起点作为已经构建好的部分。
2. 将与该起点相连且未被访问过的边加入到候选集合中。
3. 从候选集合中选择一条权值最小的边连接到未被访问过的节点,并将该节点加入到已经构建好的部分中。
4. 将新加入节点所连接且未被访问过的边加入到候选集合中。
5. 重复步骤3和步骤4,直至所有节点都被加入到已经构建好的部分中。
Prim算法C语言实现下面给出Prim算法C语言实现代码:```#include <stdio.h>#include <stdlib.h>#include <limits.h>#define MAX_VERTICES 100#define INF INT_MAXtypedef struct {int weight;int visited;} Vertex;typedef struct {int vertices[MAX_VERTICES][MAX_VERTICES]; int num_vertices;} Graph;void init_graph(Graph *graph, int num_vertices) {graph->num_vertices = num_vertices;for (int i = 0; i < num_vertices; i++) {for (int j = 0; j < num_vertices; j++) {graph->vertices[i][j] = INF;}}}void add_edge(Graph *graph, int u, int v, int weight) { graph->vertices[u][v] = weight;graph->vertices[v][u] = weight;}void prim(Graph *graph) {Vertex vertices[MAX_VERTICES];for (int i = 0; i < graph->num_vertices; i++) {vertices[i].weight = INF;vertices[i].visited = 0;}vertices[0].weight = 0;for (int i = 0; i < graph->num_vertices - 1; i++) {// 找到未访问过的权值最小的节点int min_vertex_index = -1;for (int j = 0; j < graph->num_vertices; j++) {if (!vertices[j].visited && (min_vertex_index == -1 || vertices[j].weight < vertices[min_vertex_index].weight)) { min_vertex_index = j;}}// 将该节点标记为已访问vertices[min_vertex_index].visited = 1;// 更新与该节点相连的未访问过的节点的权值for (int j = 0; j < graph->num_vertices; j++) {if (!vertices[j].visited && graph->vertices[min_vertex_index][j] < vertices[j].weight) {vertices[j].weight = graph->vertices[min_vertex_index][j];}}}// 输出最小生成树printf("Minimum Spanning Tree:\n");for (int i = 1; i < graph->num_vertices; i++) {printf("%d - %d (%d)\n", i, (i - 1), vertices[i].weight); }}int main() {Graph graph;init_graph(&graph, 6);add_edge(&graph, 0, 1, 6);add_edge(&graph, 0, 2, 1);add_edge(&graph, 0, 3, 5);add_edge(&graph, 1, 4, 3);add_edge(&graph, 2, 4, 5);add_edge(&graph, 2, 3, 5);add_edge(&graph, 2, 5, 4);add_edge(&graph, 3 ,5 ,2);prim(&graph);return EXIT_SUCCESS;}```代码解释- 定义了Vertex结构体,用于存储节点的权值和访问状态。
C语言程序设计的常用算法

C语言程序设计的常用算法1.排序算法-冒泡排序:通过多次比较和交换来将最大(小)的数移到最后(前),时间复杂度为O(n^2)。
适用于数据较少、数据基本有序的情况。
- 快速排序:通过一趟排序将待排序序列分隔成独立的两部分,其中一部分的所有元素都比另一部分的所有元素小。
然后递归地对两部分进行排序,时间复杂度为O(nlogn)。
适用于大规模数据的排序。
-插入排序:将待排序序列分为已排序和未排序两部分,每次从未排序部分取一个元素插入到已排序部分的适当位置,时间复杂度为O(n^2)。
适用于数据量较小的排序场景。
- 归并排序:将待排序序列分为若干个子序列,分别进行排序,然后再将排好序的子序列合并成整体有序的序列,时间复杂度为O(nlogn)。
适用于需要稳定排序且对内存空间要求不高的情况。
2.查找算法-顺序查找:从头到尾依次对每个元素进行比较,直到找到目标元素或者遍历完整个序列。
时间复杂度为O(n)。
- 二分查找:对于有序序列,将序列的中间元素与目标元素进行比较,根据比较结果缩小查找范围,直到找到目标元素或者查找范围为空。
时间复杂度为O(logn)。
3.图算法-广度优先(BFS):从给定的起始顶点开始,按照“先访问当前顶点的所有邻接顶点,再依次访问这些邻接顶点的所有未访问过的邻接顶点”的顺序逐层访问图中的所有顶点。
适用于寻找最短路径、连通性等问题。
-深度优先(DFS):从给定的起始顶点开始,按照“先递归访问当前顶点的一个邻接顶点,再递归访问这个邻接顶点的一个邻接顶点,直到无法再继续递归”的方式遍历图中的所有顶点。
适用于寻找路径、判断连通性等问题。
4.动态规划算法-背包问题:给定一个背包容量和一组物品的重量和价值,选择一些物品装入背包,使得装入的物品总重量不超过背包容量,且总价值最大。
利用动态规划的思想可以通过构建二维数组来解决该问题。
-最长公共子序列(LCS):给定两个序列,找出一个最长的子序列,且该子序列在两个原序列中的顺序保持一致。
最小生成树(普里姆算法)

最⼩⽣成树(普⾥姆算法):所谓⽣成树,就是n个点之间连成n-1条边的图形。
⽽最⼩⽣成树,就是权值(两点间直线的值)之和的最⼩值。
⾸先,要⽤⼆维数组记录点和权值。
如上图所⽰⽆向图:int map[7][7];map[1][2]=map[2][1]=4;map[1][3]=map[3][1]=2;......然后再求最⼩⽣成树。
具体⽅法是:1.先选取⼀个点作起始点,然后选择它邻近的权值最⼩的点(如果有多个与其相连的相同最⼩权值的点,随便选取⼀个)。
如1作为起点。
visited[1]=1;pos=1;//⽤low[]数组不断刷新最⼩权值,low[i](0<i<=点数)的值为:i点到邻近点(未被标记)的最⼩距离。
low[1]=0; //起始点i到邻近点的最⼩距离为0low[2]=map[pos][2]=4;low[3]=map[pos][3]=2;low[4]==map[pos][4]=3;low[5]=map[pos][5]=MaxInt; //⽆法直达low[6]=map[pos][6]=MaxInt;2.再在伸延的点找与它邻近的两者权值最⼩的点。
//low[]以3作当前位置进⾏更新visited[3]=1;pos=3;low[1]=0; //已标记,不更新low[2]=map[1][2]=4; //⽐5⼩,不更新low[3]=2; //已标记,不更新low[4]=map[1][4]=3; //⽐1⼤,更新后为:low[4]=map[3][4]=1;low[5]=map[1][5]=MaxInt;//⽆法直达,不更新low[6]=map[1][6]=MaxInt;//⽐2⼤,更新后为:low[6]=map[3][6]=2;3.如此类推...当所有点都连同后,结果最⽣成树如上图所⽰。
所有权值相加就是最⼩⽣成树,其值为2+1+2+4+3=12。
⾄于具体代码如何实现,现在结合POJ1258例题解释。
c语言prim算法

c语言prim算法Prim算法是一种用于求解最小生成树问题的算法,它通过逐步选择与当前生成树相邻且权重最小的边来逐步构建最小生成树。
下面是使用C语言实现Prim算法的示例代码:```c#include <stdio.h>#include <limits.h>#define V 5 // 图中顶点的数量int minKey(int key[], int mstSet[]) {int min = INT_MAX, min_index;for (int v = 0; v < V; v++) {if (mstSet[v] == 0 && 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]; // 存放顶点的键值int mstSet[V]; // 标记顶点是否已包含在最小生成树中for (int i = 0; i < V; i++) {key[i] = INT_MAX;mstSet[i] = 0;}key[0] = 0;parent[0] = -1;for (int count = 0; count < V - 1; count++) {int u = minKey(key, mstSet);mstSet[u] = 1;for (int v = 0; v < V; v++) {if (graph[u][v] && mstSet[v] == 0 && 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;}```此示例实现了Prim算法来求解给定图形的最小生成树,并且在控制台打印出了所得到的最小生成树的边及其权重。
C语言常用的入门算法

C语言常用的入门算法C语言是一门广泛应用于计算机科学和软件开发领域的编程语言。
作为一门通用的编程语言,C语言提供了丰富的算法和数据结构库,使得开发人员能够解决各种不同类型的问题。
下面是C语言入门算法的一些常见示例:1.排序算法:-冒泡排序:通过不断比较相邻的元素,并交换它们的位置来排序。
-插入排序:将未排序的元素逐一插入已排序的列表中。
-选择排序:通过重复找到最小的元素并将其放置在已排序序列的末尾来排序。
-快速排序:通过选择一个基准元素,将列表划分成较小和较大的两部分,然后对其进行递归排序。
-归并排序:将列表分成较小的子列表,然后逐个合并这些子列表。
2.查找算法:-顺序查找:逐个比较列表中的元素,直到找到匹配的元素为止。
-二分查找:在已排序的列表中通过递归或循环的方式,将待查找的元素与中间元素进行比较,以确定它可能在哪一半中。
-哈希表:通过散列函数将元素映射到一个较小的固定大小的数组(哈希表)中,并通过索引快速查找。
3.字符串算法:-字符串长度:使用循环逐个字符遍历,直到遇到字符串结束符'\0'为止,统计字符个数。
-字符串比较:逐个字符比较两个字符串的对应位置,直到遇到不相等的字符或字符串结束符。
-字符串拼接:将一个字符串的字符逐个复制到另一个字符串的末尾,直到遇到字符串结束符'\0'。
-子字符串匹配:在一个较长的字符串中查找一个较短的子字符串,常用的算法有朴素算法和KMP算法。
4.数值算法和运算:-求和、平均值、最大/最小值:循环遍历列表,累加求和,计算平均值,找出最大/最小值。
-阶乘和斐波那契数列:使用循环或递归计算给定数字的阶乘和斐波那契数列。
-幂运算和开方:通过循环或递归计算给定数字的幂和开方。
- 线性方程求解:求解形如ax + b = 0的一元线性方程。
5.图算法:-广度优先(BFS):通过遍历图的邻居节点来逐层扩展区域,通常用于查找最短路径。
-深度优先(DFS):通过遍历图的邻居节点来递归到达所有可能的节点,通常用于查找所有路径、拓扑排序等。
c语言prim算法

c语言prim算法
Prim算法,又称普里姆算法,是一种用于解决最小生成树问题的经典算法。
它以图论为基础,能够在一个具有权重的连通无向图中找到一棵包含所有顶点的树,且树的权重之和最小。
算法的思路相对简单。
假设有一个无向图G,其中顶点集合为V,边集合为E。
算法从一个起始节点开始,逐步扩展生成树的规模,最终得到最小生成树。
1. 初始化:
- 创建一个空的集合T,用于存放最小生成树的边。
- 随机选择一个起始节点s,并将其加入T。
2. 重复以下步骤,直到所有顶点都加入T:
- 在图G中找到一条边e,满足e的一个端点在T中,另一个端点不在T中,并且e的权重最小。
- 将边e加入T,将其另一个端点加入T。
3. 输出最小生成树。
Prim算法的核心在于选择权重最小的边,将其加入生成树。
通过不断扩展生成树的规模,直到包含所有顶点,就能得到最小生成树。
这个算法的时间复杂度为O(V^2),其中V是顶点的数量。
在稠密图中,Prim算法的效率可能较低。
为了提高效率,可以使用最小堆等
数据结构来优化选择最小边的过程,将时间复杂度降到O(ElogV)。
Prim算法在实际应用中有着广泛的用途,如网络设计、电力传输等领域。
它能够帮助我们找到一个具有最小总成本的连接方案,从而提高资源利用效率。
Prim算法是一种解决最小生成树问题的有效算法。
通过选择权重最小的边,逐步扩展生成树的规模,最终得到一个最小总成本的树。
它的应用范围广泛,并且在实际问题中具有重要意义。
希望通过以上的介绍,能够对Prim算法有一个更深入的理解。
最小生成树(prim算法)贪心算法

最小生成树算法Prim算法设G=(V,E)是连通带权图,V={1,2,…,n}。
构造G的最小生成树的Prim算法的基本思想是:(1)置S={1}(2)只要S是V的真子集,就作如下的贪心选择选取满足条件i ∈ S,j ∈ V-S,且c[i][j]最小的边,将顶点j添加到S中。
一直到S=V时为止。
(2)选取到的所有边恰好构成G的一棵最小生成树。
源代码://科目:算法实验4//题目:设G=(V,E)是连通带权图,V={1,2,…,n}。
构造G的最小生成树的Prim算法//作者:武叶//语言:C语言//创作时间:2012年4月14日#include"stdio.h"int point[100],key_point[100],tree[100][100]; //定义三个数组用于存放关键点和最小生成树int INT_MAX=0x7fff;void prim(int end,int V); //prim算法函数int main(){int V,E; //定义顶点数V和边数Eint i,j;int start,end,distance; //定义开始顶点start和结束顶点end,以及他们的权值distanceprintf("请输入连通带权图的边数和顶点数:");while(scanf("%d%d",&V,&E)) //开始输入你要求最小生成树的顶点数和边数{printf("\n------------------------------------");for(i=1;i<=V;i++){for(j=1;j<=V;j++)tree[i][j]=INT_MAX;}printf("\n请输入%d条边的起点和终点,以及权值。
\n",E);printf("\n----------------------------------------\n");int x=1; //用x记录输入的边数while(E--){printf("第%d条边的起点:终点:权值:",x);scanf("%d%d%d",&start,&end,&distance); //记录输入的起点、终点、权值tree[start][end]=tree[end][start]=distance;x=x+1;}prim(1,V); //调用prim计算最小生成树printf("\n");}return 0;}void prim(int end,int V){int min; //定义权值最小值minfor(int i=1;i<=V;i++){point[i]=end;key_point[i]=tree[end][i];}key_point[end]=0;for(i=2;i<=V;i++){min= INT_MAX;for(int j=1;j<=V;j++)if(key_point[j]>0 && key_point[j]<min){end=j;min=key_point[j];}printf("起点%d-->终点%d连通\n",point[end],end); //输出最小生成树的连通边key_point[end]=0;for(j=1;j<=V;j++) //继续判断条件if(tree[end][j]<key_point[j])point[j]=end,key_point[j]=tree[end][j];}}运行结果截图:答销网真情提供::文章出处::::/forum.php?mod=viewthread&tid=1533&extra=page%3D1%26filter%3Dtypeid%26typeid%3D3%26typeid%3D3。
单片机常用的14个C语言算法

引言概述:在单片机的开发中,C语言是最常用的编程语言之一。
掌握一些常用的C语言算法对于单片机的开发非常重要。
本文将介绍单片机常用的14个C语言算法之二,包括排序算法、查找算法、递归算法、动态规划算法和图算法。
正文内容:一、排序算法1. 冒泡排序:通过不断地交换相邻元素的位置,将大的元素冒泡到数组的末尾。
2. 快速排序:通过选择一个基准元素,将小于基准元素的数移动到基准元素左边,将大于基准元素的数移动到基准元素右边,然后分别对左右两部分递归地进行快速排序。
3. 插入排序:将数组分为已排序和未排序两部分,每次从未排序部分取一个元素,将其插入已排序部分的合适位置。
4. 选择排序:每次从未排序部分选择最小的元素,将其放在已排序部分的末尾。
5. 归并排序:将数组不断划分为更小的子数组,然后将子数组合并为有序数组。
二、查找算法1. 顺序查找:逐个比较数组中的元素,直到找到目标元素或者遍历完整个数组。
2. 二分查找:对于已排序的数组,通过不断将目标值与中间元素比较,并缩小搜索范围,最终找到目标元素的位置。
3. 插值查找:与二分查找类似,不同之处在于确定中间元素的位置时使用插值公式,使得查找范围更接近目标元素。
4. 哈希查找:使用哈希函数将关键字映射到一个唯一的哈希值,通过查找哈希值对应的位置来获取关键字。
5. 递归查找:通过递归地划分问题的规模,从而减小查找范围,最终找到目标元素。
三、递归算法1. 递归定义:在函数的定义中使用函数本身的方式称为递归。
2. 递归函数的特点:包含一个递归结束的条件和一个递归调用的表达式。
3. 递归算法的实现:通过不断把原问题转化为更小规模的子问题,直到满足递归结束的条件。
4. 递归算法的应用:在树、图等数据结构的遍历、搜索等问题中,递归算法被广泛使用。
5. 递归算法的优化:如尾递归优化、记忆化搜索等方法可以避免递归算法中的重复计算。
四、动态规划算法1. 动态规划的思想:将一个问题划分为多个子问题,并保存每个子问题的解,避免重复计算。
c++克鲁斯卡尔算法求最小生成树

c++克鲁斯卡尔算法求最小生成树克鲁斯卡尔算法是求解最小生成树的一种常用算法,其主要思想是将所有的边按照权值从小到大排序,然后依次加入生成树中,只要不形成环就可以加入。
C++代码实现:```#include <iostream>#include <algorithm>using namespace std;const int MAXN = 10000;const int MAXM = 100000;struct Edge {int u, v, w;} edge[MAXM];int father[MAXN];bool cmp(const Edge &a, const Edge &b) {return a.w < b.w;}int find(int x) {if (father[x] == x) return x;return father[x] = find(father[x]);}int main() {int n, m;cin >> n >> m;for (int i = 1; i <= m; i++) {cin >> edge[i].u >> edge[i].v >> edge[i].w;}sort(edge + 1, edge + m + 1, cmp);for (int i = 1; i <= n; i++) {father[i] = i;}int cnt = 0;int ans = 0;for (int i = 1; i <= m; i++) {int u = edge[i].u, v = edge[i].v, w = edge[i].w; int fu = find(u), fv = find(v);if (fu != fv) {father[fu] = fv;ans += w;cnt++;if (cnt == n - 1) break;}}cout << ans << endl;return 0;}```其中,edge数组存储边的信息,包括起点、终点和权重。
详解图的应用(最小生成树、拓扑排序、关键路径、最短路径)

详解图的应用(最小生成树、拓扑排序、关键路径、最短路径)1.最小生成树:无向连通图的所有生成树中有一棵边的权值总和最小的生成树1.1 问题背景:假设要在n个城市之间建立通信联络网,则连通n个城市只需要n—1条线路。
这时,自然会考虑这样一个问题,如何在最节省经费的前提下建立这个通信网。
在每两个城市之间都可以设置一条线路,相应地都要付出一定的经济代价。
n个城市之间,最多可能设置n(n-1)/2条线路,那么,如何在这些可能的线路中选择n-1条,以使总的耗费最少呢?1.2 分析问题(建立模型):可以用连通网来表示n个城市以及n个城市间可能设置的通信线路,其中网的顶点表示城市,边表示两城市之间的线路,赋于边的权值表示相应的代价。
对于n个顶点的连通网可以建立许多不同的生成树,每一棵生成树都可以是一个通信网。
即无向连通图的生成树不是唯一的。
连通图的一次遍历所经过的边的集合及图中所有顶点的集合就构成了该图的一棵生成树,对连通图的不同遍历,就可能得到不同的生成树。
图G5无向连通图的生成树为(a)、(b)和(c)图所示:G5G5的三棵生成树:可以证明,对于有n 个顶点的无向连通图,无论其生成树的形态如何,所有生成树中都有且仅有n-1 条边。
1.3最小生成树的定义:如果无向连通图是一个网,那么,它的所有生成树中必有一棵边的权值总和最小的生成树,我们称这棵生成树为最小生成树,简称为最小生成树。
最小生成树的性质:假设N=(V,{ E}) 是个连通网,U是顶点集合V的一个非空子集,若(u,v)是个一条具有最小权值(代价)的边,其中,则必存在一棵包含边(u,v)的最小生成树。
1.4 解决方案:两种常用的构造最小生成树的算法:普里姆(Prim)和克鲁斯卡尔(Kruskal)。
他们都利用了最小生成树的性质1.普里姆(Prim)算法:有线到点,适合边稠密。
时间复杂度O(N^2)假设G=(V,E)为连通图,其中V 为网图中所有顶点的集合,E 为网图中所有带权边的集合。
数据结构最小生成树头歌c语言

数据结构最小生成树头歌c语言一、前言数据结构中的最小生成树是一种非常重要的算法,它在网络设计、图像处理和社交网络分析等领域有着广泛的应用。
在C语言中,我们可以通过不同的数据结构来实现最小生成树算法,本文将重点介绍如何使用头歌C语言来实现最小生成树算法。
二、数据结构介绍1. 什么是最小生成树在一个连通的无向图中,如果我们要找到一个生成树,并且这个生成树的所有边的权值之和最小,那么这个生成树就是最小生成树。
最小生成树算法有Prim算法和Kruskal算法两种经典的实现方式。
2. 最小生成树的应用最小生成树广泛应用于各种场景中。
比如在计算机网络中,我们可以通过最小生成树算法来构建网络拓扑结构;在社交网络分析中,我们可以基于用户间的关系构建最小生成树,从而发现社区结构;在传感器网络中,最小生成树算法可以用于构建相互连接的传感器网络。
三、 Kruskal算法实现Kruskal算法是一种贪心算法,它的基本思想是:首先将图中的边按照权值的大小进行排序,然后依次加入权值最小的边,并且保证加入的边不会构成回路,直到生成树的边数等于节点数减一为止。
在C语言中,我们可以通过以下步骤来实现Kruskal算法:1. 定义一个结构体来表示边的信息,包括起点、终点和边的权值。
2. 根据边的权值对边进行排序。
3. 使用并查集来判断是否构成回路,如果不构成回路则加入最小生成树中。
4. 重复步骤3直到生成树的边数等于节点数减一。
实际的C语言代码如下所示:```c#include <stdio.h>#include <stdbool.h>#define MAX_EDGE 100#define MAX_VERT 100typedef struct{int from, to;int weight;} Edge;Edge edges[MAX_EDGE];int parent[MAX_VERT];void make_set(int v){parent[v] = v;}int find_set(int v){if (v == parent[v])return v;return parent[v] = find_set(parent[v]); }void union_sets(int a, int b){a = find_set(a);b = find_set(b);if (a != b)parent[b] = a;}int m本人n(){int n, m; // n为节点数,m为边数scanf("dd", n, m);for (int i = 0; i < m; i++)scanf("ddd", edges[i].from, edges[i].to, edges[i].weight);for (int i = 1; i <= n; i++)make_set(i);// 对边按照权值进行排序for (int i = 0; i < m; i++){for (int j = 0; j < m - 1 - i; j++){if (edges[j].weight > edges[j + 1].weight){Edge tmp = edges[j];edges[j] = edges[j + 1];edges[j + 1] = tmp;}}}int cost = 0;for (int i = 0; i < m; i++){if (find_set(edges[i].from) != find_set(edges[i].to)) {printf("d d d\n", edges[i].from, edges[i].to, edges[i].weight);cost += edges[i].weight;union_sets(edges[i].from, edges[i].to);}}printf("Minimum cost = d\n", cost);return 0;}```四、 Prim算法实现Prim算法是另一种最小生成树算法,在C语言中同样可以通过数据结构来实现。
c语言prim算法 -回复

c语言prim算法-回复Prim算法是一种经典的图算法,主要用于解决最小生成树问题。
在计算机科学中,图是由若干个节点和连接这些节点的边组成的一种数据结构。
最小生成树是在一个连通无向图中找到一个生成树,使得所有边的权重之和最小。
在本文中,将逐步介绍Prim算法的原理和步骤。
首先,需要了解一些基本概念。
在图中,每个节点表示一个对象,边表示对象之间的连接关系。
每条边都有一个权重,用于表示连接两个节点之间的距离或消耗。
一个生成树是一个连通图,其中包含了图中所有节点,并且通过一组边连接起来,但没有形成环路。
最小生成树是所有生成树中权重之和最小的那个。
Prim算法的基本思想是从一个起始节点开始,不断地选择与当前生成树相连的权重最小的边,并将相连的节点加入生成树中,直到所有节点都被加入为止。
具体步骤如下:1. 创建一个空的生成树。
开始时,生成树中只包含起始节点。
2. 初始化一个集合V,用于存储还未加入生成树的节点。
3. 初始化一个集合E,用于存储生成树中的边。
4. 初始化一个数组d,用于存储每个节点到生成树的距离。
开始时,将所有节点的距离设为无穷大。
5. 选择一个起始节点,将其加入生成树。
6. 将起始节点的相邻节点加入集合V,更新它们与起始节点的距离。
7. 从集合V中选择与生成树距离最小的节点v,并将其加入生成树。
8. 将节点v的相邻节点加入集合V,更新它们与生成树的距离。
9. 选择与生成树相连的最小权重边,并将其加入集合E。
10. 重复步骤7至9,直到所有节点都被加入生成树为止。
Prim算法的时间复杂度取决于选择最小权重节点的方法,可以使用优先队列实现最小堆,从而将时间复杂度降至O(ElogV),其中V表示节点数,E表示边数。
需要注意的是,Prim算法求得的最小生成树可能不唯一,但它们的权重之和是相同的。
这是因为Prim算法每次选择的边都是当前生成树和剩余节点之间最小权重的边,保证了最终生成树的权重最小。
总结一下,Prim算法是一种解决最小生成树问题的经典算法。
数据结构(三十三)最小生成树(Prim、Kruskal)

数据结构(三⼗三)最⼩⽣成树(Prim、Kruskal) ⼀、最⼩⽣成树的定义 ⼀个连通图的⽣成树是⼀个极⼩的连通⼦图,它含有图中全部的顶点,但只有⾜以构成⼀棵树的n-1条边。
在⼀个⽹的所有⽣成树中,权值总和最⼩的⽣成树称为最⼩代价⽣成树(Minimum Cost Spanning Tree),简称为最⼩⽣成树。
构造最⼩⽣成树的准则有以下3条:只能使⽤该图中的边构造最⼩⽣成树当且仅当使⽤n-1条边来连接图中的n个顶点不能使⽤产⽣回路的边 对⽐两个算法,Kruskal算法主要是针对边来展开,边数少时效率会⾮常⾼,所以对于稀疏图有很⼤的优势;⽽Prim算法对于稠密图,即边数⾮常多的情况会更好⼀些。
⼆、普⾥姆(Prim)算法 1.Prim算法描述 假设N={V,{E}}是连通⽹,TE是N上最⼩⽣成树中边的集合。
算法从U={u0,u0属于V},TE={}开始。
重复执⾏下⾯的操作:在所有u属于U,v 属于V-U的边(u,v)中找⼀条代价最⼩的边(u0,v0)并加⼊集合TE,同时v0加⼊U,直到U=V为⽌。
此时TE中必有n-1条边,则T=(V,{TE})为N的最⼩⽣成树。
2.Prim算法的C语⾔代码实现/* Prim算法⽣成最⼩⽣成树 */void MiniSpanTree_Prim(MGraph G){int min, i, j, k;int adjvex[MAXVEX]; /* 保存相关顶点下标 */int lowcost[MAXVEX]; /* 保存相关顶点间边的权值 */lowcost[0] = 0;/* 初始化第⼀个权值为0,即v0加⼊⽣成树 *//* lowcost的值为0,在这⾥就是此下标的顶点已经加⼊⽣成树 */adjvex[0] = 0; /* 初始化第⼀个顶点下标为0 */for(i = 1; i < G.numVertexes; i++) /* 循环除下标为0外的全部顶点 */{lowcost[i] = G.arc[0][i]; /* 将v0顶点与之有边的权值存⼊数组 */adjvex[i] = 0; /* 初始化都为v0的下标 */}for(i = 1; i < G.numVertexes; i++){min = INFINITY; /* 初始化最⼩权值为∞, *//* 通常设置为不可能的⼤数字如32767、65535等 */j = 1;k = 0;while(j < G.numVertexes) /* 循环全部顶点 */{if(lowcost[j]!=0 && lowcost[j] < min)/* 如果权值不为0且权值⼩于min */{min = lowcost[j]; /* 则让当前权值成为最⼩值 */k = j; /* 将当前最⼩值的下标存⼊k */}j++;}printf("(%d, %d)\n", adjvex[k], k);/* 打印当前顶点边中权值最⼩的边 */lowcost[k] = 0;/* 将当前顶点的权值设置为0,表⽰此顶点已经完成任务 */for(j = 1; j < G.numVertexes; j++) /* 循环所有顶点 */{if(lowcost[j]!=0 && G.arc[k][j] < lowcost[j]){/* 如果下标为k顶点各边权值⼩于此前这些顶点未被加⼊⽣成树权值 */lowcost[j] = G.arc[k][j];/* 将较⼩的权值存⼊lowcost相应位置 */adjvex[j] = k; /* 将下标为k的顶点存⼊adjvex */}}}}Prim算法 3.Prim算法的Java语⾔代码实现package bigjun.iplab.adjacencyMatrix;/*** 最⼩⽣成树之Prim算法*/public class MiniSpanTree_Prim {int lowCost; // 顶点对应的权值public CloseEdge(Object adjVex, int lowCost) {this.adjVex = adjVex;this.lowCost = lowCost;}}private static int getMinMum(CloseEdge[] closeEdges) {int min = Integer.MAX_VALUE; // 初始化最⼩权值为正⽆穷int v = -1; // 顶点数组下标for (int i = 0; i < closeEdges.length; i++) { // 遍历权值数组,找到最⼩的权值以及对应的顶点数组的下标if (closeEdges[i].lowCost != 0 && closeEdges[i].lowCost < min) {min = closeEdges[i].lowCost;v = i;}}return v;}// Prim算法构造图G的以u为起始点的最⼩⽣成树public static void Prim(AdjacencyMatrixGraphINF G, Object u) throws Exception{// 初始化⼀个⼆维最⼩⽣成树数组minSpanTree,由于最⼩⽣成树的边是n-1,所以数组第⼀个参数是G.getVexNum() - 1,第⼆个参数表⽰边的起点和终点符号,所以是2 Object[][] minSpanTree = new Object[G.getVexNum() - 1][2];int count = 0; // 最⼩⽣成树得到的边的序号// 初始化保存相关顶点和相关顶点间边的权值的数组对象CloseEdge[] closeEdges = new CloseEdge[G.getVexNum()];int k = G.locateVex(u);for (int j = 0; j < G.getVexNum(); j++) {if (j!=k) {closeEdges[j] = new CloseEdge(u, G.getArcs()[k][j]);// 将顶点u到其他各个顶点权值写⼊数组中}}closeEdges[k] = new CloseEdge(u, 0); // 加⼊u到⾃⾝的权值0for (int i = 1; i < G.getVexNum(); i++) { // 注意,这⾥从1开始,k = getMinMum(closeEdges); // 获取u到数组下标为k的顶点的权值最短minSpanTree[count][0] = closeEdges[k].adjVex; // 最⼩⽣成树第⼀个值为uminSpanTree[count][1] = G.getVexs()[k]; // 最⼩⽣成树第⼆个值为k对应的顶点count++;closeEdges[k].lowCost = 0; // 下标为k的顶点不参与最⼩权值的查找了for (int j = 0; j < G.getVexNum(); j++) {if (G.getArcs()[k][j] < closeEdges[j].lowCost) {closeEdges[j] = new CloseEdge(G.getVex(k), G.getArcs()[k][j]);}}}System.out.print("通过Prim算法得到的最⼩⽣成树序列为: {");for (Object[] Tree : minSpanTree) {System.out.print("(" + Tree[0].toString() + "-" + Tree[1].toString() + ")");}System.out.println("}");}} 4.举例说明Prim算法实现过程 以下图为例: 测试类:// ⼿动创建⼀个⽤于测试最⼩⽣成树算法的⽆向⽹public static AdjacencyMatrixGraphINF createUDNByYourHand_ForMiniSpanTree() {Object vexs_UDN[] = {"V0", "V1", "V2", "V3", "V4", "V5", "V6", "V7", "V8"};int arcsNum_UDN = 15;int[][] arcs_UDN = new int[vexs_UDN.length][vexs_UDN.length];for (int i = 0; i < vexs_UDN.length; i++) // 构造⽆向图邻接矩阵for (int j = 0; j < vexs_UDN.length; j++)if (i==j) {arcs_UDN[i][j]=0;} else {arcs_UDN[i][j] = arcs_UDN[i][j] = INFINITY;}arcs_UDN[0][5] = 11;arcs_UDN[1][2] = 18;arcs_UDN[1][6] = 16;arcs_UDN[1][8] = 12;arcs_UDN[2][3] = 22;arcs_UDN[2][8] = 8;arcs_UDN[3][4] = 20;arcs_UDN[3][6] = 24;arcs_UDN[3][7] = 16;arcs_UDN[3][8] = 21;arcs_UDN[4][5] = 26;arcs_UDN[4][7] = 7;arcs_UDN[5][6] = 17;arcs_UDN[6][7] = 19;for (int i = 0; i < vexs_UDN.length; i++) // 构造⽆向图邻接矩阵for (int j = i; j < vexs_UDN.length; j++)arcs_UDN[j][i] = arcs_UDN[i][j];return new AdjMatGraph(GraphKind.UDN, vexs_UDN.length, arcsNum_UDN, vexs_UDN, arcs_UDN);}public static void main(String[] args) throws Exception {AdjMatGraph UDN_Graph = (AdjMatGraph) createUDNByYourHand_ForMiniSpanTree();MiniSpanTree_Prim.Prim(UDN_Graph, "V0");} 输出为:通过Prim算法得到的最⼩⽣成树序列为: {(V0-V1)(V0-V5)(V1-V8)(V8-V2)(V1-V6)(V6-V7)(V7-V4)(V7-V3)} 分析算法执⾏过程:从V0开始:-count为0,k为0,closeEdges数组的-lowCost为{0 10 INF INF INF 11 INF INF INF},adjVex数组为{V0,V0,V0,V0,V0,V0,V0,V0,V0}-⽐较lowCost,于是k为1,adjVex[1]为V0,minSpanTree[0]为(V0,V1),lowCost为{0 0 INF INF INF 11 INF INF INF}-k为1,与V1的权值⾏⽐较,得到新的-lowCost为:{0 0 18 INF INF 11 16 INF 12},adjVex数组为{V0,V0,V1,V0,V0,V0,V1,V0,V1}-⽐较lowCost,于是k为5,adjVex[5]为V0,minSpanTree[1]为(V0,V5),lowCost为{0 0 18 INF INF 0 16 INF 12}-k为5,与V5的权值⾏⽐较,得到新的-lowCost为{0 0 18 INF 26 0 16 INF 12},adjVex数组为{V0,V0,V1,V0,V5,V0,V1,V0,V1}-⽐较lowCost,于是k为8,adjVex[8]为V1,minSpanTree[2]为(V1,V8),lowCost为{0 0 18 INF INF 0 16 INF 0}... 三、克鲁斯卡尔(Kruskal)算法 1.Kruskal算法描述 Kruskal算法是根据边的权值递增的⽅式,依次找出权值最⼩的边建⽴的最⼩⽣成树,并且规定每次新增的边,不能造成⽣成树有回路,直到找到n-1条边为⽌。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
C语言代码如下:
#include<stdio.h>
#include<windows.h>
#define TURE 999
typedef struct ArcNode
{ char vexs[10];
int edgs[10][10];
int n,e;
}MGraph;
struct edg{
int v1;
//输入顶点数,边数
for(i=0;i<G->n;i++)
{
getchar();
printf("请输入第%d个顶点:",i+1);
scanf("%c",&(G->vexs[i]));
//输入¨顶点
}
for(i=0(j=0;j<G->n;j++)
G->edgs[i][j]=0;
for(k=0;k<G->e;k++)
{
printf("请输入第%d条边的顶点权值(格式如¨i j):",k+1);
getchar();
scanf("%c %c %d",&a,&b,&weight);
m=0;n=0; for( m=0;G->vexs[m]!=a;m++); for( n=0;G->vexs[n]!=b;n++);
closedge[i].lowcost=G->edgs[v][i]; closedge[i].adjvex=v; } closedge[v].lowcost=TURE; for (i=1;i<G->n;i++) { min=100; for(j=0;j<G->n;j++) if (closedge[j].lowcost!=TURE && closedge[j].lowcost!=0) { if (closedge[j].lowcost<min) { min=closedge[j].lowcost;
int v2;
int cost;
}A[10],B[10];
//创建图
void GreateMGraph(MGraph *G)
{ int i,j,k,weight,m,n;
int ch1,ch2;
char a,b;
printf("请输入顶点数和边数(格式如4):");
scanf("%d %d",&(G->n),&(G->e));
k=j; } } printf("(%c,%c,%d) ", G->vexs[closedge[k].adjvex], G->vexs[k], min); closedge[k].lowcost=TURE; for (j=0;j<G->n;j++)
if (closedge[j].lowcost!=TURE) if(G->edgs[k][j]<closedge[j].lowcost||closedge[j].lowcost==0 ) { closedge[j].lowcost=G->edgs[k][j]; closedge[j].adjvex=k; }
ch1=m;ch2=n; G->edgs[ch1][ch2]=weight;G->edgs[ch2][ch1]=weight;
} }
void prim(MGraph *G, int v) {
int i,j,k,min; struct { int adjvex; int lowcost; } closedge[10]; for (i=0;i<G->n;i++) {
} }
int main(void) {
MGraph *G,a; char ch1; G=&a; printf("建立图的邻接矩阵\n"); GreateMGraph(G); getchar(); ch1=1; printf("\n");
printf("最小生成树 " ); printf("prim算法输出为a:");
prim(G,0); system("pause"); }
运行结果截图:
在线编译成功;