克鲁斯卡尔数据结构中图的克鲁斯卡尔算法的基本思想是?
克鲁斯卡尔 时间:2021-06-08 阅读:(
)
无论用普里姆算法或者是克鲁斯卡尔算法求最小生成树,得出的结果应该一样么?
不总是一样的,克鲁斯卡尔算法是精确算法,即每次都能求得最优解,但对于规模较大的最小生成树问题,求解速度较慢。
而普里姆算法是近似求解算法,虽然对于大多数最小生成树问题都能求得最优解,但相当一部分求得的是近似最优解。
这是我个人见解。
最小生成树 普里姆算法和克鲁斯卡尔算法
kruskal算法的时间复杂度主要由排序方法决定,其排序算法只与带权边的个数有关,与图中顶点的个数无关,当使用时间复杂度为O(eloge)的排序算法时,克鲁斯卡算法的时间复杂度即为O(eloge),因此当带权图的顶点个数较多而边的条数较少时,使用克鲁斯卡尔算法构造最小生成树效果最好!
克鲁斯卡尔算法
假设 WN=(V,{E}) 是一个含有 n 个顶点的连通网,则按照克鲁斯卡尔算法构造最小生成树的过程为:先构造一个只含 n 个顶点,而边集为空的子图,若将该子图中各个顶点看成是各棵树上的根结点,则它是一个含有 n 棵树的一个森林。
之后,从网的边集 E 中选取一条权值最小的边,若该条边的两个顶点分属不同的树,则将其加入子图,也就是说,将这两个顶点分别所在的两棵树合成一棵树;反之,若该条边的两个顶点已落在同一棵树上,则不可取,而应该取下一条权值最小的边再试之。
依次类推,直至森林中只有一棵树,也即子图中含有 n-1条边为止。
普里姆算法
假设 WN=(V,{E}) 是一个含有 n 个顶点的连通网,TV 是 WN 上最小生成树中顶点的集合,TE 是最小生成树中边的集合。
显然,在算法执行结束时,TV=V,而 TE 是 E 的一个子集。
在算法开始执行时,TE 为空集,TV 中只有一个顶点,因此,按普里姆算法构造最小生成树的过程为:在所有“其一个顶点已经落在生成树上,而另一个顶点尚未落在生成树上”的边中取一条权值为最小的边,逐条加在生成树上,直至生成树中含有 n-1条边为止。
--以上传自/valyanprogramming/blog/item/1bc960e6095f9726b93820d9.html
1.Kruskal
//题目地址:/JudgeOnline/problem?id=1258
#include<cstdio>
#include<cstdlib>
#include<iostream>
using namespace std;
struct node
{
int v1;
int v2;
int len;
}e[10000];//定义边集
int cmp(const void *a,const void *b)//快排比较函数
{
return ((node*)a)->len-((node*)b)->len;
}
int v[100],a[100][100];//v为点集
void makeset(int n)
{
for(int i=0;i<n;i++)
v[i]=i;
}
int find(int x)
{
int h=x;
while(h!=v[h])
h=v[h];
return h;
}
int main()
{
int n,i,j,r1,r2,p,total;
while(scanf("%d",&n)!=EOF)
{
p=0;
total=0;
makeset(n);
for(i=0;i<n;i++)
{
for(j=0;j<n;j++)
{
scanf("%d",&a[i][j]);
e[p].v1=i;
e[p].v2=j;
e[p].len=a[i][j];
p++;
}
}
qsort(e,p,sizeof(e[0]),cmp);
for(i=0;i<p;i++)
{
r1=find(e[i].v1);
r2=find(e[i].v2);
if(r1!=r2)
{
total+=e[i].len;
v[r1]=r2;
}
}
printf("%d
",total);
}
system("pause");
return 0;
}
2.Prim
//题目地址同上
#include <iostream>
using namespace std;
#define M 101
#define maxnum 100001
int dis[M][M];
int prim(int n)
{
bool used[M]={};
int d[M],i,j,k;
for(i=1; i<=n; i++)
d[i] = dis[1][i];
used[1] = true;
int sum=0;
for(i=1; i<n; i++){
int temp=maxnum;
for(j=1; j<=n; j++){
if( !used[j] && d[j]<temp ){
temp = d[j];
k = j;
}
}
used[k] = true;
sum += d[k];
for(j=1; j<=n; j++){
if( !used[j] && dis[k][j]<d[j] )
d[j] = dis[k][j]; // 与Dijksta算法的差别之处
}
}
return sum;
}
int main()
{
int n,i,j;
while( cin>>n ){
for(i=1; i<=n; i++){
for(j=1; j<=n; j++){
scanf("%d",&dis[i][j]);
if( !dis[i][j] )
dis[i][j] = maxnum;
}
}
cout<<prim(n)<<endl;
}
return 0;
}
代码来自网络数据结构里提到的普里母和克鲁斯卡尔分别是哪个国家的?
普里母算法和克鲁斯卡尔方法求最小生成树完整程序
1、普里姆算法(Prim算法),图论中的一种算法,可在加权连通图里搜索最小生成树。
意即由此算法搜索到的边子集所构成的树中,不但包括了连通图里的所有顶点(英语:Vertex (graph theory)),且其所有边的权值之和亦为最小。
该算法于1930年由捷克数学家沃伊捷赫·亚尔尼克(英语:Vojtěch Jarník)发现;并在1957年由美国计算机科学家罗伯特·普里姆(英语:Robert C. Prim)独立发现;1959年,艾兹格·迪科斯彻再次发现了该算法。
因此,在某些场合,普里姆算法又被称为DJP算法、亚尔尼克算法或普里姆-亚尔尼克算法
2、Kruskal算法是一种用来寻找最小生成树的算法,由Joseph Kruskal在1956年发表。
用来解决同样问题的还有Prim算法和Boruvka算法等。
三种算法都是贪婪算法的应用。
和Boruvka算法不同的地方是,Kruskal算法在图中存在相同权值的边时也有效。
数据结构中图的克鲁斯卡尔算法的基本思想是?
基本思想是:设有一个有n个顶点的连通网络N={V,E},最 初先构造一个只有n个顶点,没有边的非连通图 T={ V,¢},图中每个顶点自成一个 连通分量。
当在E中选到一条具有最小权值的边时,若该边的两个顶点落在不同的连通 分量上,则将此边加人到T中;否则将此边舍去,重新选择一条权值最小的边。
如此重复 下去,直到所有顶点在同一个连通分量上为止。
diyvm怎么样?diyvm商家VPS主机均2GB内存起步,三个地区机房可选,使用优惠码后每月69元起;DiyVM独立服务器开设在香港沙田电信机房,CN2线路,5M带宽,自动化开通上架,最低499元/月,配置是L5630*2/16G内存/120G SSD硬盘。DiyVM是一家成立于2009年的国人主机商,提供的产品包括VPS主机、独立服务器租用等,产品数据中心包括中国香港、日本大阪和美国洛杉矶等,...
RepriseHosting是成立于2012年的国外主机商,提供独立服务器租用和VPS主机等产品,数据中心在美国西雅图和拉斯维加斯机房。商家提供的独立服务器以较低的价格为主,目前针对西雅图机房部分独立服务器提供的优惠仍然有效,除了价格折扣外,还免费升级内存和带宽,商家支持使用支付宝或者PayPal、信用卡等付款方式。配置一 $27.97/月CPU:Intel Xeon L5640内存:16GB(原...
profitserver怎么样?profitserver是一家成立于2003的主机商家,是ITC控股的一个部门,主要经营的产品域名、SSL证书、虚拟主机、VPS和独立服务器,机房有俄罗斯、新加坡、荷兰、美国、保加利亚,VPS采用的是KVM虚拟架构,硬盘采用纯SSD,而且最大的优势是不限制流量,大公司运营,机器比较稳定,数据中心众多。此次ProfitServer正在对德国VPS(法兰克福)、西班牙v...
克鲁斯卡尔为你推荐
cpu监控win10自带cpu温度监控svn服务器搭建怎样搭建本地svn服务器环境eagleeye《鹰眼》的男主角是谁?oa办公系统下载oa办公软件哪里可以下载?模式识别算法算法是编程么?考研学模式识别方向,编程多么?asp大马一句话木马中的大马和小马的作用各是什么?云盘网谁知道免费的网盘?币众筹众筹平台开发哪家好什么是生态系统生态系统的我主要特征是什么?什么是生态系统生态系统的结构是什么
个人域名注册 免费试用vps cybermonday google电话 腾讯云盘 谷歌香港 域名优惠码 网通服务器ip hnyd 京东商城双十一活动 建立邮箱 免费高速空间 空间技术网 根服务器 东莞服务器托管 申请免费空间 金主 阿里云邮箱个人版 privatetracker SmartAXMT800 更多