最小生成树(C语言实现)

article/2025/9/16 10:28:31

求这个网的最小生成树

/** 普里姆算法和克鲁斯卡尔算法求最小生成树* 采用邻接矩阵存储**/
#include<stdio.h>#define MAX_VERTEX_NUM 20
//图的定义
typedef struct 
{int vertexNum;int edgeNum;char vertex[MAX_VERTEX_NUM];int arc[MAX_VERTEX_NUM][MAX_VERTEX_NUM];
}Graph,*PGraph;//辅助数组元素
typedef struct 
{int from;int to;int weight;int flag;
}ArrayNode; //构造无向网
void createdGraph(PGraph g)
{int i,j;g->vertexNum=6;g->edgeNum=10;for(i=0;i<g->vertexNum;i++)g->vertex[i]='A'+i;for(i=0;i<g->vertexNum;i++)for(j=0;j<g->vertexNum;j++)g->arc[i][j]=0;g->arc[0][1]=6;g->arc[0][2]=1;g->arc[0][3]=5;g->arc[1][0]=6;g->arc[1][2]=5;g->arc[1][4]=3;g->arc[2][0]=1;g->arc[2][1]=5;g->arc[2][3]=5;g->arc[2][4]=6;g->arc[2][5]=4;g->arc[3][0]=5;g->arc[3][2]=5;g->arc[3][5]=2;g->arc[4][1]=3;g->arc[4][2]=6;g->arc[4][5]=6;g->arc[5][2]=4;g->arc[5][3]=2;g->arc[5][4]=6;
}//初始化最小生成树
void initTree(PGraph tree)
{int i,j;tree->vertexNum=6;tree->edgeNum=5;for(i=0;i<tree->vertexNum;i++)tree->vertex[i]='0';for(i=0;i<tree->vertexNum;i++)for(j=0;j<tree->vertexNum;j++)tree->arc[i][j]=0;
}//普里姆算法求最小生成树
void prim(PGraph g,PGraph tree)
{int i,j,k;int index;  //指向权值最小的边ArrayNode  edgeArray[MAX_VERTEX_NUM*2]; //辅助数组 int length=0; //数组长度int n=1;  //统计数组已加入多少个顶点//初始状态把第一个顶点加入树中tree->vertex[0]='A';printf("%-3c",tree->vertex[0]);i=0;while(1){//寻找与顶点i相接且这条边的另一个顶点不在树中的边,存入edgeArray数组中for(j=0;j<g->vertexNum;j++){if(g->arc[i][j] > 0){//判断这条边的另一个顶点在不在树中for(k=0;k<tree->vertexNum;k++){if(tree->vertex[k] == g->vertex[j])break;}if(k == tree->vertexNum){edgeArray[length].from=i;edgeArray[length].to=j;edgeArray[length].weight=g->arc[i][j];edgeArray[length].flag=0;length++;}}}//从数组中选择权值最小的边index=-1;for(j=0;j<length;j++){if(index == -1 && edgeArray[j].flag == 0)index=j;if(edgeArray[j].flag==0 && edgeArray[j].weight < edgeArray[index].weight)index=j;}//在树中加入一个顶点,且把这条权值最小的边加入树中tree->vertex[edgeArray[index].to]='A'+edgeArray[index].to;edgeArray[index].flag=1;tree->arc[edgeArray[index].from][edgeArray[index].to]=edgeArray[index].weight;tree->arc[edgeArray[index].to][edgeArray[index].from]=edgeArray[index].weight;//当这个顶点加入树中时,与这个顶点相邻的边不可加入树中for(k=0;k<length;k++){if(edgeArray[k].to == edgeArray[index].to)edgeArray[k].flag=1;}i=edgeArray[index].to;printf("%-3c",tree->vertex[i]);n++;//当有g->vertexNum个顶点时,最小生成树构造完成if(n==g->vertexNum)break;}
}//判断两个顶点是否连通(广度优先搜索)
int connected(PGraph tree,int from,int to)
{int i,j,k;int vertex[MAX_VERTEX_NUM];//看成队列int front,rear;if(from==to)return 1;front=rear=0;//把第一个顶点存入数组vertex[rear++]=from;//遍历treewhile(front<=rear){i=vertex[front];for(j=0;j<tree->vertexNum;j++)if(tree->arc[i][j]>0){if(j==to)return 1;//判断此顶点是否在队列中for(k=0;k<rear;k++)if(vertex[k] == j)break;if(k==rear)vertex[rear++]=j;}front++;}return 0;
}//克鲁斯卡尔算法求最小生成树
void kruskal(PGraph g,PGraph tree)
{ArrayNode  edgeArray[MAX_VERTEX_NUM]; //辅助数组 int length=0;int i,j,k,index,n;//顶点先加入树中for(i=0;i<tree->vertexNum;i++)tree->vertex[i]=i+'A';//1.把所有的边有序(从小到大)的插入edgeArray数组中for(i=0;i<g->vertexNum;i++)for(j=0;j<g->vertexNum;j++){if(i<j && g->arc[i][j]>0){//寻找插入的位置indexfor(k=0;k<length;k++){if(edgeArray[k].weight > g->arc[i][j])break;}index=k;//移位for(k=length;k>index;k--)edgeArray[k]=edgeArray[k-1];//插入length++;edgeArray[index].flag=0;edgeArray[index].from=i;edgeArray[index].to=j;edgeArray[index].weight=g->arc[i][j];}}//2.从小到大取出n-1条边构造最小生成树n=0;while(n < g->vertexNum-1){//从小到大取一条符合要求的边for(k=0;k<length;k++)if(edgeArray[k].flag==0 && connected(tree,edgeArray[k].from,edgeArray[k].to)==0){break;}//把这条边加入树中tree->arc[edgeArray[k].from][edgeArray[k].to]=edgeArray[k].weight;tree->arc[edgeArray[k].to][edgeArray[k].from]=edgeArray[k].weight;edgeArray[k].flag=1;printf("%-3d",edgeArray[k].weight);n++;}
}void main()
{Graph graph;Graph tree;createdGraph(&graph);initTree(&tree);printf("普里姆算法树中顶点加入的顺序:\n");prim(&graph,&tree);printf("\n");initTree(&tree);printf("克鲁斯卡尔算法树中边加入的顺序:\n");kruskal(&graph,&tree);printf("\n");
}

 


http://chatgpt.dhexx.cn/article/rNy7i9PG.shtml

相关文章

最小生成树(C语言)

最小生成树问题&#xff08;C语言&#xff09; 所谓一个 带权图 的最小生成树&#xff0c;就是原图中边的权值最小的生成树 &#xff0c;所谓最小是指边的权值之和小于或者等于其它生成树的边的权值之和。 kruskal 克鲁斯卡尔算法&#xff08;Kruskal&#xff09;是一种使用贪…

最小生成树kruskal算法

最小生成树kruskal算法 概述算法分析代码 概述 克鲁斯卡尔 ( K r u s k a l ) (Kruskal) (Kruskal)算法是求连通网的最小生成树的另一种方法。与普里姆 ( P r i m ) (Prim) (Prim)算法不同&#xff0c;它的时间复杂度为 O ( e l o g e ) O(eloge) O(eloge)(e为网中的边数)&…

最小生成树:

定义&#xff1a; 将图中的 n 结点用 n-1 条边连接起来&#xff0c;使其各个边的权值之和最小的生成树。 普里姆算法&#xff1a; 从点的角度出发。 1、start 数组的值表示起始点的下标&#xff0c;start 的下标代表目的顶点&#xff1b;lowcost 数组的下标代表目的顶点&…

图——最小生成树

图——最小生成树 1. 基本概念 在一个连通无向图G(V, E)中&#xff0c;对于其中的每条边(u,v)∈E&#xff0c;赋予其权重w(u, v)&#xff0c;则最小生成树问题就是要在G中找到一个连通图G中所有顶点的无环子集T⊆E&#xff0c;使得这个子集中所有边的权重之和w(T) ∑ ( u , …

最小生成树的Kruskal算法-详解

最小生成树的Kruskal算法 一、 什么是最小生成树 1.1 最小生成树定义&#xff1a; 一个有 n 个结点的连通图的生成树是原图的极小连通子图&#xff0c;且包含原图中的所有 n 个结点&#xff0c;并且有保持图连通的最少的边。最小生成树可以用kruskal&#xff08;克鲁斯卡尔&a…

最小生成树(C语言简单实现)

最小生成树 本文参考自《大话数据结构》 一个连通图的生成树是一个极小的连通子图&#xff0c;它含有图中全部的顶点&#xff0c;但只有足以构成一棵树的n-1条边。我们把构造连通网的最小代价生成树称为最小生成树 。 找连通网的最小生成树&#xff0c;经典的有两种算法&#…

最小生成树怎么画?

介绍最小生成树的图形画法~以下图为例&#xff1a; 1、从1开始&#xff0c;以1为顶点画圈。在红色线经过的部分中&#xff0c;可见权重分别为6、1、5&#xff0c;最小权重为1。如下图。 2、以上图中得到的1、3为顶点的图中&#xff0c;继续画线&#xff0c;图为黄色线部分。经过…

最小生成树算法

最小生成树算法 生成树的概念最小生成树算法Prim算法Kruskal算法 生成树的概念 若图是连通的无向图或强连通的有向图&#xff0c;则从其中任一顶点出发&#xff0c;调用一次 d f s dfs dfs或者 b f s bfs bfs后&#xff0c;可以系统的访问图中所有顶点。若图是有根的有向图 &a…

【图】最小生成树

最小生成树&#xff1a;构造连通网的最小代价生成树。 最小生成树有两种算法&#xff1a;普利姆算法、克鲁斯卡尔算法。 普利姆&#xff08;Prim&#xff09;算法 加点&#xff0c;选择相邻点中边权最小的 需要两个一维数组&#xff0c;一个存权值&#xff0c;另一个存起始点…

最小生成树-Kruskal算法

数据结构:最小生成树-Kruskal算法 什么是最小生成树&#xff0c;最小生成树就是求图中把所有点都访问到的最短路径的长度 Kruskal算法采用的是边贪心思想&#xff0c;我们先大概讲一下它的大概思想&#xff0c;首先我们先假设先隐藏所有的边&#xff0c;这样每个点会成为一个连…

最小生成树(kruskal算法)

一、概述 最小生成树问题顾名思义&#xff0c;概括来说就是路修的最短。 接下来引入几个一看就明白的定义&#xff1a; 最小生成树相关概念&#xff1a; 带权图&#xff1a;边赋以权值的图称为网或带权图&#xff0c;带权图的生成树也是带权的&#xff0c;生成树T各边的权值…

最小生成树、最短路径树

一、最小生成树与最短路径树的区别 最小生成树能够保证整个拓扑图的所有路径之和最小&#xff0c;但不能保证任意两点之间是最短路径。 应用如网络部线&#xff0c;把所有的电脑(服务器&#xff1f;&#xff09;都连起来用的网线(光纤&#xff1f;&#xff09;最少&#xff0c…

【图解算法】最小生成树

今天我们介绍图论中的另一部分&#xff0c;最小生成树。 对图的最短路感兴趣的同学可以看&#xff1a; 【图解算法】一次解决最短路径问题 目录 1. 最小生成树简介2. Prim算法2.1 模板题2.2 思路模板2.3 代码实现2.3 prim 算法的优化 3. Kruskal算法3.1 模板题3.2 思路模板3.3…

数据结构—最小生成树

目录 一、生成树 二、最小生成树&#xff08;代价最小树&#xff09; 三、求最小生成树 1、Prim算法&#xff08;普里姆&#xff09; 2.Kruskal 算法&#xff08;克鲁斯卡尔&#xff09; 3.Prim算法和Kruskal算法对比 一、生成树 连通图的生成树是包含图中全部顶点的一个…

最小生成树详解

目录 最小生成树简介 什么是树 什么是生成树 什么是最小生成树 最小生成树的做法 Kruscal&#xff08;克鲁斯卡尔&#xff09;算法 思路 代码 其他算法 最小生成树简介 什么是树 树&#xff08;tree&#xff09;是一种特殊的图&#xff0c;一个图要成为树要满足三个条…

最小生成树的实现(C语言)

今天做洛谷的时候刷到好多图论的题&#xff0c;发现自己在这一方面算法的掌握还是有待提高啊。在这就先介绍最小生成树的算法吧。 最小生成树 最小生成树&#xff08;minimum spanning tree&#xff09;是由n个顶点&#xff0c;n-1条边&#xff0c;将一个连通图连接起来&…

详解: 最小生成树

详解: 最小生成树算法 最小生成树&#xff08;Minimum Spanning Tree, MST&#xff09;是在一个给定的无向图G(V, E)中求一棵树&#xff0c;使得这棵树有图G的所有顶点&#xff0c;且所有边都来自图G中的边&#xff0c;并且满足整棵树的边权之和最小. 最下生成树满足如下性质…

最小生成树

目录 一、最小生成树定义&#xff1a; 二、普里姆算法&#xff08;Prim&#xff09; 三、Kruskal算法&#xff08;克鲁斯卡尔&#xff09; 小结&#xff1a; 下一篇&#xff1a;最短路径算法 问题&#xff1a; 一、最小生成树定义&#xff1a; 对于一个带权连通无向图G(V,E)&am…

最小生成树——Prim算法(详细图解)

目录 最小生成树的概念 经典题目 prim算法简介 prim算法解析 &#xff08;详细图解&#xff09; 代码实现 代码实战 最小生成树的概念 在一给定的无向图G (V, E) 中&#xff0c;(u, v) 代表连接顶点 u 与顶点 v 的边&#xff0c;而 w(u, v) 代表此的边权重&#xff0c;若…

最小生成树入门(图解)

1.什么是最小生成树 来看百度百科的定义 一个有 n 个结点的连通图的生成树是原图的极小连通子图&#xff0c;且包含原图中的所有 n个结点&#xff0c;并且有保持图连通的最少的边。最小生成树可以用kruskal&#xff08;克鲁斯卡尔&#xff09;算法或prim&#xff08;普里姆&am…