Prim算法实现

  最小生成树是数据结构中图的一种重要应用,它的要求是从一个带权无向完全图中选择n-1条边并使这个图仍然连通(也即得到了一棵生成树),同时还要考虑使树的权最小。 为了得到最小生成树,人们设计了很多算法,最著名的有prim算法和kruskal算法。时间复杂度分别为O(n2)和O(eloge)

     假设V是途中顶点的集合,E是边的集合,T是最小生成树的边的集合。U为在最小生成树上点的集合,那么V-U为不在最小生成树上的点的集合。

  Prim算法的基本思想:

  1.首先选取一个点作为起始点,比如说1顶点,加入到U集合中

      2.在所有u∈U,v∈V-U的边(u,v)∈E中,找一条权最小的边(u,v),将此边加进集合T中,并将此边的非U中顶点加入U中。此步骤的功能是在边集E中找一条边,要求这条边满足以下条件:首先边的两个顶点要分别在顶点集合U和V-U中,其次边的权要最小。找到这条边以后,把这条边放到边集T中,并把这条边上不在U中的那个顶点加入到U中。

     3:如果U=V,则算法结束;否则重复步骤2。可以把本步骤看成循环终止条件。我们可以算出当U=V时,步骤2共执行了n-1次(设n为图中顶点的数目),TE中也增加了n-1条边,这n-1条边就是需要求出的最小生成树的边。

      代码实现:

      总共需要3个数组,U【i】,标记节点是否已经加入到最小生成树当中

                              d【i】,记录U集合中到达V-U集合中顶点的最小边的权值

                              b【i】,记录最小权值边的顶点,即是从哪个点过来的边

#include <iostream>
using namespace std;
int edge[5][5]={{0,11,3,10,17},{11,0,12,2,1},{3,12,0,8,5},{10,2,8,0,1},{17,1,5,1,0}};
int u[5]={0}; //0表示都不在最小生成树中
int d[5]; //存放不在最小生成树上的节点到树上节点的最小的距离
int b[5]; //存放源节点,即最小生成树上的节点
int count=0;
void Print();
void Prim()
{
u[0]=1;
count++;
for(int i=1;i<5;i++)
{
d[i]=edge[0][i];
b[i]=0;
}
while(count<5)
{
int Max=10000;
int p;
for(int i=0;i<5;i++)
{
if(!u[i]&&d[i]<Max)
{
Max=d[i];
p=i;
}
}
u[p]=1;
count++;
for(int i=0;i<5;i++)
{
if(!u[i]&&d[i]>edge[p][i])
{
d[i]=edge[p][i];
b[i]=p;
}
}

}
}
int main()
{
int i;
Print();
Prim();
for(i=0;i<5;i++)
{
cout<<b[i]<<"";
}
cout<<endl;
for(i=0;i<5;i++)
{
cout<<u[i]<<"";
}
cout<<endl;
for(i=0;i<5;i++)
{
cout<<d[i]<<"";
}
cout<<endl;
system("pause");
return 0;
}
void Print()
{
for(int i=0;i<5;i++)
{
for(int j=0;j<5;j++)
cout<<edge[i][j]<<"";
cout<<endl;
}
}



转载于:https://www.cnblogs.com/dlutxm/archive/2011/11/04/2236607.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值