Prim算法和Kruskal算法都能从连通图找出最小生成树。区别在于Prim算法是以某个顶点出发挨个找,而Kruskal是先排序边,每次选出最短距离的边再找。

一、Prim(普里姆算法)算法:

Prim算法实现的是找出一个有权重连通图中的最小生成树,即:具有最小权重且连接到所有结点的树。(强调的是树,树是没有回路的)。

Prim算法是这样来做的:

首先以一个结点作为最小生成树的初始结点,然后以迭代的方式找出与最小生成树中各结点权重最小边,并加入到最小生成树中。加入之后如果产生回路则跳过这条边,选择下一个结点。当所有结点都加入到最小生成树中之后,就找出了连通图中的最小生成树了。

Prim算法最小生成树查找过程:

C语言实现:

#include <stdio.h>
#include <stdlib.h>
#define maxint 1073741824
int main()
{FILE *input=fopen("input.txt","r"),*out=fopen("output.txt","w");int n,m,i,j,x,y,w;fscanf(input,"%d %d",&n,&m);int map[n][n],E[m][3],tree[m],Mst[n][n];/*Mst表示最小生成树的邻接矩阵,map是原图,E是边集,其中E[0]和E[1]是边的两个顶点,E[2]是边的权值,tree是用于判断原图的点是否在最小生成树中*/memset(tree,0,sizeof(tree));for(i=0; i<n; i++){for(j=0; j<n; j++){ map[i][j]=maxint;Mst[i][j]=maxint;}E[i][0]=E[i][1]=maxint;}for(i=0; i<m; i++){fscanf(input,"%d %d %d",&x,&y,&w);if(w<map[x][y]){map[x][y]=w;map[y][x]=w;}}int min=maxint,next=0,now=0,k=0;tree[0]=1;for(i=0; i<n; i++){for(j=0; j<n; j++){if(map[now][j]!=maxint && tree[j]==0){E[k][0]=now;E[k][2]=map[now][j];E[k++][1]=j;}}for(j=0; j<k; j++){if(E[j][2]<min && tree[E[j][1]]==0){min=E[j][2];x=E[j][0];y=E[j][1];next=y;}}tree[next]=1;now=next;Mst[x][y]=map[x][y];Mst[y][x]=map[y][x];min=maxint;}for(i=0; i<n; i++){for(j=0; j<n; j++){if(Mst[i][j]==maxint) //判断两点是否连通fprintf(out,"00 "); //美化输出,不必多加探究else{fprintf(out,"%d ",Mst[i][j]); //输出生成树的邻接矩阵,要输出树的自己可以根据邻接矩阵的数据进行加工}}fprintf(out,"\n");}fclose(input);fclose(out);return 0;
} // 程序未考虑不是连通图的情况,修改很简单,判断生成树的节点数量是否等于原图的节点数量//如果小于(不会有大于)则本图不是连通图//其实prim和迪杰斯特拉算法核心有相似之处

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

Kruskal算法与Prim算法的不同之处在于,Kruskal在找最小生成树结点之前,需要对所有权重边做从小到大排序。将排序好的权重边依次加入到最小生成树中,如果加入时产生回路就跳过这条边,加入下一条边。当所有结点都加入到最小生成树中之后,就找出了最小生成树。

C语言实现:

/*  Kruskal.cCopyright (c) 2002, 2006 by ctu_85All Rights Reserved.I am sorry to say that the situation of unconnected graph is not concerned */
#include "stdio.h"
#define maxver 10
#define maxright 100
int G[maxver][maxver],record=0,touched[maxver][maxver];
int circle=0;
int FindCircle(int,int,int,int);
int main()
{int path[maxver][2],used[maxver][maxver]; int i,j,k,t,min=maxright,exsit=0;int v1,v2,num,temp,status=0;restart:printf("Please enter the number of vertex(s) in the graph:\n");scanf("%d",&num);if(num>maxver||num<0){printf("Error!Please reinput!\n");goto restart;}for(j=0;j<num;j++)for(k=0;k<num;k++){if(j==k){G[j][k]=maxright;used[j][k]=1;touched[j][k]=0;}elseif(j<k){re:printf("Please input the right between vertex %d and vertex %d,if no edge exists please input -1:\n",j+1,k+1);scanf("%d",&temp);if(temp>=maxright||temp<-1){printf("Invalid input!\n");goto re;}if(temp==-1)temp=maxright;G[j][k]=G[k][j]=temp;used[j][k]=used[k][j]=0;touched[j][k]=touched[k][j]=0;}}for(j=0;j<num;j++){path[j][0]=0;path[j][1]=0;}for(j=0;j<num;j++){status=0;for(k=0;k<num;k++)if(G[j][k]<maxright){status=1;break;}if(status==0)break;}for(i=0;i<num-1&&status;i++){for(j=0;j<num;j++)for(k=0;k<num;k++)if(G[j][k]<min&&!used[j][k]){v1=j;v2=k;min=G[j][k];}if(!used[v1][v2]){used[v1][v2]=1;used[v2][v1]=1;touched[v1][v2]=1;touched[v2][v1]=1;path[0]=v1;path[1]=v2;for(t=0;t<record;t++)FindCircle(path[t][0],path[t][0],num,path[t][0]);if(circle){/*if a circle exsits,roll back*/circle=0;i--;exsit=0;touched[v1][v2]=0;touched[v2][v1]=0;min=maxright;}else{record++;min=maxright;}}}if(!status)printf("We cannot deal with it because the graph is not connected!\n");else{for(i=0;i<num-1;i++)printf("Path %d:vertex %d to vertex %d\n",i+1,path[0]+1,path[1]+1);}return 1;
}
int FindCircle(int start,int begin,int times,int pre)
{ /* to judge whether a circle is produced*/int i;for(i=0;i<times;i++)if(touched[begin]==1){if(i==start&&pre!=start){circle=1;return 1;break;}elseif(pre!=i)FindCircle(start,i,times,begin);elsecontinue;}return 1;
}

无疑,Kruskal算法在效率上要比Prim算法快,因为Kruskal只需要对权重边做一次排序,而Prim算法则需要做多次排序。尽管Prim算法每次做的算法涉及的权重边不一定会涵盖连通图中的所有边,但是随着所使用的排序算法的效率的提高,Kruskal算法和Prim算法之间的差异将会清晰的显性出来。

转载于:https://www.cnblogs.com/tham/p/6827367.html

Prim算法和Kruskal算法相关推荐

  1. 【Java数据结构与算法】第十九章 贪心算法、Prim算法和Kruskal算法

    第十九章 贪心算法.Prim算法和Kruskal算法 文章目录 第十九章 贪心算法.Prim算法和Kruskal算法 一.贪心算法 1.介绍 2.支付问题 二.Prim算法 1.最小生成树 2.介绍 ...

  2. matlab实现prim算法,Prim算法和Kruskal算法的Matlab实现

    Prim算法和Kruskal算法的Matlab实现 <计算机仿真>期末大作业 Prim算法和Kruskal算法的Matlab实现 05605刘禹050697(30) 连线问题应用举例: 欲 ...

  3. 【最小生成树】Prim算法和Kruskal算法的区别对比

    Prim算法和Kruskal算法都是从连通图中找出最小生成树的经典算法- 从策略上来说,Prim算法是直接查找,多次寻找邻边的权重最小值,而Kruskal是需要先对权重排序后查找的- 所以说,Krus ...

  4. 加权无向图与最小生成树(Prim算法和Kruskal算法)

    目录 0 引入 1 图的最小生成树定义及相关约定 2 最小生成树原理 2.1 性质 2.2 切分定理 3 贪心思想 4 Prim算法 4.1 算法步骤 4.2 API设计 4.3 Java代码演示 5 ...

  5. 求的带权图最小生成树的Prim算法和Kruskal算法

    求的带权图最小生成树的Prim算法和Kruskal算法 最小生成树的概念 最小生成树其实是最小权重生成树的简称. 一个连通图可能有多个生成树.当图中的边具有权值时,总会有一个生成树的边的权值之和小于或 ...

  6. 【数据结构】最小生成树问题(Prim算法和Kruskal算法)

    相关概念 连通图与它的生成树 连通图的生成树是包含图中全部顶点的一个极小连通子图.若图的顶点数为n,则它的生成树含有n-1条边.一个连通图可能拥有多个生成树. 最小生成树(Minimum-Spanni ...

  7. 作业1-采用Prim算法和Kruskal算法构造最小生成树

    采用Prim算法和Kruskal算法构造最小生成树 实验报告 1.问题 2.解析 (1)Prim算法 (2)Kruskal算法 3.设计 (1)Prim算法 (2)Kruskal算法 4.分析 (1) ...

  8. 最小生成树之Prim算法和Kruskal算法

    一个连通图可能有多棵生成树,而最小生成树是一副连通加权无向图中一颗权值最小的生成树,它可以根据Prim算法和Kruskal算法得出,这两个算法分别从点和边的角度来解决. Prim算法 输入:一个加权连 ...

  9. 最小生成树-Prim算法和Kruskal算法

    转载自:https://www.cnblogs.com/biyeymyhjob/archive/2012/07/30/2615542.html Prim算法 1.概览 普里姆算法(Prim算法),图论 ...

最新文章

  1. 1081 Rational Sum 有理数类型题处理 需再做
  2. python常用函数-python常用函数与用法示例
  3. 对称密码获取(OJ)
  4. Web Api无法访问 404
  5. MySQL笔记-binlog理论及binlog回滚恢复数据
  6. Js获取移动设备分辨率
  7. javaeye改名之后
  8. 介绍7个适合普通大学生参加的编程比赛/考试(注:有的比赛如蓝桥杯有多种赛别,本文仅介绍其中的程序设计/编程比赛)
  9. 根据 Excel 整理好的文件夹名称批量给文件夹重命名
  10. 在浏览器输入URL,按下回车之后的流程
  11. Mini MP3 Player模块无法正常播放
  12. Windows系统本地搭建DedeCMS网站教程
  13. 大事件!PCIe SSD与SATA SSD同价啦
  14. Django数据库字段及参数
  15. Android-回传数据(装备选择)
  16. 你真的会用@Transactional吗?
  17. EBM、DEA-SBM模型集合大全(普通的、非期望产出的、超效率的、CRS、VRS条件下的)
  18. 网页中点击按钮弹出QQ聊天窗口的功能实现
  19. 汽车导航linux系统设计,基于ARM-Linux平台车载导航系统设计与实现
  20. 为什么苹果内购总是失败_苹果内购审核那些被拒的原因

热门文章

  1. vxworks 实时操作系统
  2. 第一章 TestNG框架自动化简述
  3. PYTHON之路DAY3
  4. emacs 新手笔记(四) —— 使用 dired 完成一些简单的文件和目录操作
  5. 浏览器老是自动跳出广告垃圾网页
  6. java--面向接口编程
  7. easyui和Ajax在mvc3中的权限设置
  8. [存储引擎基础知识]InnoDB与MyISAM的六大区别(非原创)
  9. (原)产品化:架构、过程管理
  10. 利用kinect检测任意平面