算法分析的一般步驟:
1、文字描述:如果一個算法文字描述不清楚,就說明思路不清楚,也不可能寫好。
prim算法是實現圖的最小生成樹。既然是圖,就假設包含n個頂點,m條邊。prim算法是從頂點出發的,其算法時間復雜度與頂點數目有關系。
(注意:prim算法適合稠密圖,其時間復雜度為O(n^2),其時間復雜度與邊得數目無關,而kruskal算法的時間復雜度為O(eloge)跟邊的數目有關,適合稀疏圖。)
算法思路:從某個頂點開始,假設v0,此時v0屬於最小生成樹結點中的一個元素,該集合假設u,剩下的V-v0為待判定的點,此時選取u中的頂點到V-v0中頂點的一個路徑最小的邊,並且將其中非u中的頂點加入到u中,循環直到u中的頂點包含圖所有的頂點為止。
算法在選取最小路徑的時候需要優化,具體思路:w[]數組保存各個頂點的最短路徑,b[]數組保存到i頂點最短路徑的頂點,比如,到0號頂點最短的路徑是<v0,v3>,那么w[0]=<v0,v3>,b[0]=3;這樣每次找最小路徑就不是o(n*n)的代價了。
2、舉例說明:

3、程序實現與說明:
#include <stdio.h>
#include <stdlib.h>
#define count 6
void prim(int a[][count],int u[],int w[],int b[],int n)
{
int i=0,j=0,m=0,min=100;
for(i=0;i<count;i++)
{
u[i]=0;//初始化0,說明沒有訪問過
w[i]=a[0][i];//初始每個頂點最短路徑為到0頂點的距離
b[i]=0;//初始每個頂點都指向0頂點
}
u[0]=1;//賦值1,從0頂點開始
for(i=1;i<n;i++)
{
min=100;
j=0;
for(m=1;m<n;m++)
{
if(!u[m] && w[m]<min)//很關鍵,得到到訪問頂點到未訪問頂點的最短路徑以及對應頂點j
{
min=w[m];
j=m;
}
}
u[j]=1;//把下一個頂點標為已訪問
printf("%d,%d\n",j+1,b[j]+1);//輸出結果
for(m=1;m<n;m++)
{
if(!u[m] && a[j][m]<w[m])//此時,u集合里面多了一個頂點j,要重新更新最短路徑以及對應的頂點
{
w[m]=a[j][m];
b[m]=j;
}
}
}
}
int main()
{
int u[count],w[count],b[count],a[count][count];
int i=0,j=0;
for(i=0;i<count;i++)
{
for(j=0;j<count;j++)
{
a[i][j]= 100;
}
}
a[0][1]=6,a[0][2]=1,a[0][3]=5;
a[1][0]=6,a[1][2]=5,a[1][4]=3;
a[2][0]=1,a[2][1]=5,a[2][3]=5,a[2][4]=6,a[2][5]=4;
a[3][0]=5,a[3][2]=5,a[3][5]=2;
a[4][1]=3,a[4][2]=6,a[4][5]=6;
a[5][3]=2,a[5][2]=4,a[5][4]=6;
prim(a,u,w,b,count);
return 0;
}
4、時間復雜度:o(n*n)
參考博客:https://www.cnblogs.com/nannanITeye/p/3446424.html

