【最小生成樹】prim算法


算法分析的一般步驟:

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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM