引题:
刚刚完成了最小生成树与最短路径的学习,发现最小生成树中的prim算法与最短路径问题中Dijkstra算法机其的相似。于是想对这两种方法进行一下下比较。
prim算法:
对于最小生成树问题,prim算法可以说是比较难以理解的算法了(个人看法)这种算法比较繁琐。不过,本人的表达能力是相当差。所以就根据例子说罢!
<pre name="code" class="cpp">const int inf=999999;
int map[110][110];//创建map二维数组储存图表
int dis[110];//dis数组记录每2个点间最小权值
int vis[100];//visited数组标记某点是否已访问
int sum;//代表所求的权值之和
void prim(int n)
{
int i,j;
int pos;
memset(vis,0,sizeof(vis));
for(i=1; i<=n; i++)
{
dis[i]=map[1][i];//第一次给dis数组赋值
}
vis[1]=1;//从某点开始,分别标记和记录该点
for(i=1; i<n; i++) //再运行n-1次,剩下的n-1个点
{
//找出最小权值并记录位置
int min=inf;
for(j=1; j<=n; j++)
{
if(!vis[j] && dis[j]<min)
{
min=dis[j];
pos=j;
}
}
if(min>=inf) break;
//最小权值累加
sum+=min;
vis[pos]=1;//标记该点
for(j=1; j<=n; j++)
{
if(!vis[j] && map[pos][j]<dis[j])//更新权值
{
dis[j]=map[pos][j];
}
}
}
}
在用这种方法时,一定要注意:
1,在这个函数中的后方,在更新权值之前一定要判断(min<inf),如果不满足那么就说明这个最小数在这个点(一般为最后一处)处的距离是无穷大(也就是不和任何一个点相连);那么,就结束函数,进而退出。因为最小生成树所求的是将所有点连接后所用的最短近距离(费用),所以sum的累加就一定要放在这个判断之后。
2,而在最后对权值的更新时的判断时,vis[j]==0这一句必须要有,这表明该点并不是前方已经标记的点,也就是并未连接到最小生成树中的点。
Dijkstra算法:
与最小生成树不同,最小路径问题所关注的并不是所有点的问题,而是最短路径问题。这二者的区别就像是去街上时,是为了“逛”,还是为了“买”。