最小生成树算法

C语言代码部分来自小甲鱼的《数据结构与算法》

文章目录

    • 最小生成树算法
  • 一、普里姆(Prim)算法
    • 1.C语言代码
    • 2.算法思路
  • 二、克鲁斯卡尔(Kruskal)算法
    • 1.C语言代码
    • 2.算法思路

最小生成树:一个有 n 个结点的连通图的生成树是原图的 极小连通子图,且包含原图中的所有 n 个结点,并且有保持图连通的最少的边。

​ 最小生成树可以用kruskal(克鲁斯卡尔)算法或prim(普里姆)算法求出,它们考虑问题的出发点是:为使生成树上边的权值之和达到最小,则应使生成树中每一条边的权值尽可能的小。

​ 普里姆算法是以某个顶点为起点,逐步找到每个顶点上最小权值的边来构建最小生成树。克鲁斯卡尔算法则换一种思路,从边出发,因为权值是在边上,所以直接去找最小权值的边来构建生成树。

区别:当边较多顶点较少时,用普里姆算法比较快;当边较少顶点较多时,用克鲁斯卡尔算法比较有优势

一、普里姆(Prim)算法

1.C语言代码

#include "math.h"
#include "stdio.h"#define MAXVEX 50typedef struct MGraph
{char vex[MAXVEX];       // 顶点集合int numVertexes;           // 顶点数int numedg;           // 边数int arc[MAXVEX][MAXVEX]; // 邻接矩阵
}MGraph;
//=============================================//
//=============================================////Prim算法生成最小生成树
void MiniSpanTree_Prim(MGraph G)
{int min,i,j,k;int adjvex[MAXVEX]; //保存相关顶点下标int lowcost[MAXVEX]; //保存相关顶点间边的权值lowcost[0]=0;       //V0作为最小生成树的根开始遍历,权值为0(当走到哪里时,显示所有联结的边)adjvex[0]=0;        //V0第一个加入(这是路径)//初始化操作for(i=1;i<G.numVertexes;i++){lowcost[i]=G.arc[0][i];  //将邻接矩阵第0行所有权值先加入数组adjvex[i]=0;             //初始化全部先为V0的下标}//真正构造最小生成树的过程for(i=1;i<G.numVertexes;i++){min=INFINITY;  //初始化最小权值为不可能数值infj=1;k=0;//遍历全部顶点while (j<G.numVertexes){//找出lowcaost数组已存储的最小权值(查找最小可走边)if(lowcost[j]!=0 && lowcost[j]<min){min=lowcost[j];k=j;        //将发现的最小权值的下标存入k,以待使用。}j++;}//打印当前顶点边权值最小的边printf("(%d,%d)",adjvex[k],k);  //adjvex是路径lowcost[k]=0;  //将当前顶点的权值设置为0,表示此顶点已经完成任务,进行下一个顶点的遍历//邻接矩阵k行逐个遍历全部顶点for(j=1;j<G.numVertexes;j++){if(lowcost!=0 && G.arc[k][j]<lowcost[j]){lowcost[j]=G.arc[k][j];adjvex[j]=k;}}}
}

2.算法思路

  1. 定义lowcost[i]**“当前”**最小生成树所能达到图中(非“当前”最小生成树中的)第i个顶点的最小权值;定义 adjvex[i]为“当前”最小生成树中第i个顶点与的第adjvex[i]个顶点相连接。
  2. 初始化:设置“当前”最小生成树仅包括第一个顶点,lowcost[i]设为之该顶点到图中顶点的距离;adjvex[i]=0,因为此时“当前”最小生成树中仅有一个顶点。
  3. 循环(不包括第一个顶点,因为第一个顶点已经在初始化中包含在了最小生成树中):从lowcost[i]中选出最小非零权值,并将相应的该顶点加入最小生成树,输出并更新lowcost数组和adjvex数组。

二、克鲁斯卡尔(Kruskal)算法

1.C语言代码

#include "math.h"
#include "stdio.h"#define MAXVEX 50
#define MAGEDGE MAXVEX*MAXVEX/2typedef struct Edge
{int begin;//边的起点int end;//边的终点int weight;//边的权值}Edge;    //权值非0的边的存储结构typedef struct MGraph
{char vex[MAXVEX];       // 顶点集合int numVertexes;           // 顶点数int numEdges;           // 边数int arc[MAXVEX][MAXVEX]; // 邻接矩阵
}MGraph;//Kruskal算法生成最小生成树
int Find(int *parent, int f)  //若f在"当前"最小生成树中,则f顺位至生成树的叶结点
{while(parent[f] > 0){f=parent[f];}return f;
}void MiniSpanTree_Kruskal(MGraph G)
{int i,n,m;Edge edges[MAGEDGE];  //定义边集数组int parent[MAXVEX];   //定义parent数组用来判断边与边是否形成环路//初始化for(i=0;i< G.numVertexes;i++){parent[i]=0;}for(i=0;i<G.numEdges;i++){n=Find(parent,edges[i].begin);m=Find(parent,edges[i].end);if(n!=m)    //如果n==m,则形成环路,不满足!{//将此边的结尾顶点放入下标为起点的parent数组中,表示此顶点已经在生成树集合中parent[n]=m;   //"当前"最小生成树中,叶结点m的父母为n,printf("(%d,%d) %d",edges[i].begin,edges[i].end,edges[i].weight);}}
}

2.算法思路

宗旨

在形成最小生成树的过程中:新添边相应的(在树中的)结点仅仅可能是叶结点与叶结点、叶结点与孤立结点、孤立结点与孤立结点

在建立最小生成树时,不断向“当前”最小生成树中添加新边,添加顺序按照边的权值从小到大排列:

  • 若添加的边相应的顶点都不在树中,则直接添加;

  • 若添加的边的仅有一个相应的顶点是在树中的结点,则通过Find不断寻找该结点在树中的孩子而得到的叶结点,与另一个结点(孤立顶点)相连;

  • 若添加的边相应的顶点都是树中的结点,且通过Find函数不断寻找树中这两个结点在树中的孩子,而顺位到叶结点时,这两个结点相等,则不添加(若添加会形成环),若不相等,则添加。

#根据上图的例子所进行的演示parent数组0 1 2 3 4 5 6 7 8-----------------1.初始化      0|0|0|0|0|0|0|0|02.对每一条边的顶点运行Find函数,并更新parent数组-----------------
(4,7)->(4,7)  0|0|0|0|7|0|0|0|0   #孤立结点与孤立结点之间的边(经过Find函数后不变)-----------------
(2,8)->(2,8)  0|0|8|0|7|0|0|0|0-----------------
(0,1)->(0,1)  1|0|8|0|7|0|0|0|0-----------------
(0,5)->(1,5)  1|5|8|0|7|0|0|0|0  -----------------
(1,8)->(5,8)  1|5|8|0|7|8|0|0|0-----------------
(3,7)->(3,7)  1|5|8|7|7|8|0|0|0   #叶结点与孤立结点之间的边(经过Find函数后不变)-----------------
(1,6)->(8,6)  1|5|8|7|7|8|0|0|6-----------------
(5,6)->(6,6)  1|5|8|7|7|8|0|0|6-----------------
(1,2)->(6,6)  1|5|8|7|7|8|0|0|6-----------------
(6,7)->(6,7)  1|5|8|7|7|8|7|0|6   #此时是两个叶结点相连接(经过Find函数后不变)-----------------
(3,4)->(7,7)  1|5|8|7|7|8|7|0|6-----------------
(3,8)->(7,7)  1|5|8|7|7|8|7|0|6-----------------
(2,3)->(7,7)  1|5|8|7|7|8|7|0|6-----------------
(3,6)->(7,7)  1|5|8|7|7|8|7|0|6-----------------
(4,5)->(7,7)  1|5|8|7|7|8|7|0|6
#=====================================
#=====================================
#由parent数组建立的最小生成树             0 > 1 > 5 > 8 > 6 > 7 < 4^       ^2       3

数据结构与算法|最小生成树算法(普里姆算法、克鲁斯卡尔算法)相关推荐

  1. 最小生成树-普利姆和克鲁斯卡尔算法

    目录 最小生成树 普利姆算法 算法介绍 代码 克鲁斯卡尔算法 算法介绍 步骤解析 回路 代码实现 最小生成树主要是用于解决修路问题等类似问题,要将所有顶点连通,并且权值之和最小. 最小生成树 给定一个 ...

  2. 【算法基础12】最小生成树的两种解法(普里姆、克鲁斯卡尔)

    一.稠密图:朴素版prim算法 主要思想:每次从树外的结点中找到一个距离树最近的点加入树,将这段路径长度计入最小生成树的路径长度中,然后依据新的树更新树外结点距离树的距离,再次找到最近点加入,直到所有 ...

  3. 最小生成树之普里姆算法

    为了能够讲明白这个算法,我们先构造网图的邻接矩阵,如图7-6-3的右图所示. 也就是说,现在我们已经有了一个存储结构为MGraph的MG(见<邻接矩阵创建图>).MG有9个顶点,它的二维数 ...

  4. JAVA-数据结构与算法-修路问题(普里姆算法)和公交站问题(克鲁斯卡尔算法)

    修路问题(普里姆算法) 最小生成树,给定一个带权的无向连通图,如何选择一颗生成树,使树上所有边上权的总和为最小:N个顶点,N-1条边 普里姆算法,在包含n个顶点的连通图中,找出只有n-1条边,包含所有 ...

  5. 数据结构(五)图---最小生成树(普里姆算法)

    一:最小生成树 (一)定义 我们把构造连通网的最小代价生成树称为最小生成树或给定一个带权的无向连通图,如何选取一棵生成树,使树上所有边上权的总和为最小,这叫最小生成树. (二)什么是最小生成树? 1. ...

  6. 【HDU - 1301】Jungle Roads(并查集+最小生成树)(内附最小生成树两种算法 克鲁斯特尔算法amp;amp;普里姆算法)

    题干: Jungle Roads Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) ...

  7. 普里姆(Prim)算法(P算法):修路问题

    1,应用场景-修路问题 如图,此时有7个村庄['A', 'B', 'C', 'D', 'E', 'F', 'G'],现在需要把这7个村庄连通 村庄之间的连接线表示可能修路的图示,权值表示举例 此时,如 ...

  8. 普里姆(Prim)算法

    普里姆(Prim)算法 普里姆(Prim)算法思想 普里姆(Prim)算法是一某个顶点为起点,逐步找各顶点最小权值的边来构建最小生成树. 换一种说法: 从任意一顶点 v0 开始选择其最近顶点 v1 构 ...

  9. 第六章图-算法6.8普里姆算法

    第六章图-算法6.8普里姆算法 代码实现 #pragma once #include <iostream>using namespace std;//图的邻接矩阵存储(创建无向图) //表 ...

  10. 数据结构与算法(7-3)最小生成树(普里姆(Prim)算法和克鲁斯卡尔(Kruskal)算法)

    目录 一.最小生成树简介 二.普里姆算法(Prim) 1.原理 2.存储 2-1.图顶点和权: 2-3. 最小生成树: 3.Prim()函数 3-1.新顶点入树 3-2.保留最小权 3-3. 找到最小 ...

最新文章

  1. 30个学习大数据挖掘的重要知识点!
  2. OpenCV数字图像处理(5) 像素访问之添加椒盐实例 通道分离与合并
  3. 使用wrk进行性能测试
  4. jquery实现登录失败提示_浅谈jQuery的verify验证码
  5. 牛客网学习笔记-day01
  6. 同一条sql insert 有时快有时慢 引发的血案
  7. Github出现连接超时
  8. 遍历Page的Controls集合
  9. ThreadPoolExecutor 的三种提交任务方式
  10. 直播连麦怎么自动化测试
  11. 【离散数学】关于欧拉图与哈密顿图的讨论
  12. OceanBase | OBCA认证考试
  13. 北斗系统学习—JT808协议用C语言解析
  14. PHP微信公众开发笔记(二)
  15. opencv:log()函数
  16. 大乱斗ps4好玩吗_《马里奥赛车》夺冠,网友票选“最好玩的马里奥游戏”
  17. 大学生交友平台——项目启动篇
  18. 量子物理:薛定谔的猫探讨
  19. 北京信息科技大学第十一届程序设计竞赛(重现赛)H andy和购物
  20. 大数累加(高精度/C++)

热门文章

  1. 奈飞win10安装包_win10安装包下载-原版win10安装包下载v10.0.19041.1-西西软件下载
  2. kotlin设置按钮不可点击_3dmax渲染720全景效果图动画流程,学习VR动画不可错过的必备知识...
  3. 经验总结 | R语言整理数据常用小技巧
  4. 基于功能连接梯度的可重复生物标志物探索研究框架——Toward a connectivity gradient-based framework for reproducible biomarker
  5. R关于一些字符串报错
  6. ABB机器人控制柜各模块指示灯状态含义详解
  7. 一个关于考勤统计的sql研究
  8. 测试开发工作者日记:2020.10.12
  9. MT6739 充电电量计代码架构变化梳理
  10. Python爬虫笔记——HTML基础认识