最小生成樹算法(一)--對prim算法的理解


7.4.1 prim算法

 

 

              用prim算法求圖的最小生成樹:

1)      由兩個數組記錄prim求最小生成樹的過程中所需的信息

a)      Lowcost[Max],記錄最小生成樹中每個【葉子結點】和【其他頂點】組成的所有邊的權重,沒有邊的,權重就是

                                           i.           長度就是頂點的個數

b)      Adjvex[Max],記錄Lowcost[Max]數組中,每條邊所對應的一個頂點,也就是說,這個邊是屬於這個頂點的,Adjvex[Max]記錄的就是這個頂點在圖中的下標(可以比喻成是一個線性函數,Adjvex[Max]就是自變量的集合,Lowcost[Max]就是函數值的集合)

c)       Adjvex[Max] 的 元素 與 元素對應的下標構成的邊,是在最小生成書中的,對應下標的Adjvex[Max]的元素,就是這條邊的權重

d)      有這麼幾個要解決的問題:

                                           i.           選出Lowcost[Max]數組中的元素

1.       Lowcost[0] = 0 ,Adjvex[0] = 0  -> 將V0添加到最小生成樹中,也就是最小生成樹的根

2.       Lowcost數組的初始值就是【V0參與生成所有邊的權重】的集合

                                          ii.           根據Lowcost[Max]數組數據與 鄰接矩陣中,第【最小生成樹新添加頂點的下標】行的數據比較,確定Adjvex[Max]數組的元素,並且將較小的邊,替換Lowcost[Max]中對應下標的邊(相當於是設置自變量,和函數值)

                                         iii.           選出Lowcost[Max]數組後,找出最小的權重的邊,並添加到最小生成樹,權重爲0,就算是添加到最小生成樹中,所以每次選出之後,都要將Lowcost[i] = 0,k =i (記錄最小權重邊的下標)(一旦成爲最小生成樹的一部分,權重(函數值)=0)

(Adjvex[k],k)就是當前的最小權重邊

                                         iv.           將鄰接矩陣中的第k行的數據與 Lowcost數組中的比較

滿足(lowcost[j] !=0 && arc[k][j] < lowcost[j])

è lowcost[j] = arc[k][j]  Adjvex[j] = k

這其實就是將【新添加到最小生成樹中的邊】的【另一個頂點(比如V1)所參加生成的邊中(權重信息存儲在鄰接矩陣的第1行),權重小於lowcost對應的值的邊】添加到lowcost數組中

                                   lowcost[j]!=0 表示已經在最小生成樹中的邊不參與比較

2)      代碼解析:

       void MiniSpanTree_Prim(MGraph G)

       {

              int min,i,j,k;

              int adjvex[Max];                  //存儲lowcost[]存儲的邊的一個頂點,元素與對應下標組成邊

              int lowcost[Max];                //存儲最小生成樹所有葉子結點的所有邊的權重

              lowcost[0] = 0;                    //將V0放到最小生成樹中,V0到V0是沒有權值的

              adjvex[0] = 0;                      // V0到V0是沒有邊的

              //初始化兩個數組

              for(i = 1;i < G.numVertex; i++)

              {

                     lowcost[i] = G.arc[0][i];

                     adjvex[i]= 0;

              }

              //循環圖中的每一個頂點

              for(i = 1; i < G.numVertex;i++)

              {

                     min = 65535;

                     j = 1;             //因爲V0已經在最小生成樹中,所以從下標爲1的頂點開始

                     k = 0;

                     while(j < G.numVertex)

                     {

                            // lowcost[i] != 0 表示頂點沒有在最小生成樹中

                            // lowcost[i] <min 找出當前lowcost數組中最小的元素

                            if(lowcost[i] != 0&& lowcost[i] < min)

                            {

                                   min =lowcost[i];

                                   k = j;

                            }

                            j++;

                     }

                     cout << adjvex[k]<< k;      //可以是其他的操作

                     lowcost[k] = 0;                    //將lowcost數組中最小元素置0(也就是附在頂點k上的某條邊的權重置0,表示k頂點加入最小生成樹中)

                     //更新lowcost數組元素,將現有的lowcost數組中的元素,依次與鄰接矩陣第k行元素比較,較小的就替換lowcost數組中對應的元素

                     // lowcost[j] != 0表示已經在最小生成樹中的頂點不用遍歷

                     for(j = 1; j <G.numVertex; j++)

                     {

                            if(lowcost[j] != 0&& G.arc[k][j] < lowcost[j])

                            {

                                   //依次與鄰接矩陣第k行元素比較,較小的就替換lowcost數組中對應的元素

                                   lowcost[j] =G.arc[k][j];

                                   adjvex[j] =k;         //將下標爲k的頂點存入adjvex數組,k,j 組成一條邊

                            }

                     }

              }            

       }

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章