算法分析的一般步驟:
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