演算法思想:可取圖中任意乙個頂點v作為生成樹的根,之後若要往生成樹上新增頂點w,則在頂點v和w之間必定存在一條邊。並且該邊的權值在所有連通頂點v和w之間的邊中取值最小。
一般情況下,假設n個頂點分成兩個集合:u(包含已落在生成樹上的結點)和v-u(尚未落在生成樹上的頂點),則在所有連通u中頂點和v-u中頂點的邊中選取權值最小的邊
c語言**如下:
[cpp]
view plain
copy
?
//最小生成樹 普里姆演算法 採用鄰接矩陣儲存
void minispantree(mgraph *g)
for (i=1; inumvertexes; ++i)
++j;
} printf("(%d, %d)", adjvex[k], k); //輸出當前頂點邊中權值最小的邊
lowcost[k] = 0; //將當前頂點的權值設為0,表示此頂點已經完成任務
for (j=1; jnumvertexes; ++j)
} } }
//最小生成樹 普里姆演算法 採用鄰接矩陣儲存
void minispantree(mgraph *g)
for (i=1; inumvertexes; ++i)
}}}
首先是變數的定義,min在每次迴圈中都存放著lowcost陣列中最小的權值。
adjvex與lowcost陣列中的下標分別對應了該圖中的頂點,如下標為1對應了第2個頂點(頂點的序號從0開始)。
例如adjvex[3] = 5 lowcost[3] = 8即表示序號為5的頂點(即第6個頂點)到序號為3(兩個陣列的下標都為3 即第4個頂點)的頂點的邊的權值為8
接著初始化lowcost[0]與adjvex[0]為0,即表示第0號結點加入生成樹,lowcost[i] = 0表示第i個結點加入到生成樹中
然後 乙個迴圈將adjvex陣列的值全都置為0並且將v0到其他頂點的權值都存入lowcost陣列中。
乙個包含所有頂點的大迴圈,所有的工作都在該迴圈體內完成
①假設現在是第一次迴圈 即第乙個頂點加入生成樹,第23行~33行,求得所有與該結點相鄰的頂點的邊上的最小的權值,並將該權值存放min中,而與其相鄰的那個頂點的序號存入k中。即找到乙個頂點k並且v0到k的權值是所有v0的鄰接點中最小的。
②/輸出當前頂點邊中權值最小的邊 即輸出adjvex[k], k 因為是第一次迴圈 所有adjvex[k] = 0, k即剛才所得到的那個權值最小的相鄰的頂點的序號。即表示adjvex[k]號頂點到k號頂點
③lowcost[k] = 0; 表示 第k號頂點已經加入到生成樹種
④第36行~43行 if (lowcost[j]!=0 && g->arc[k][j]arc[k][j]; 即k頂點到j頂點的權值為 g->arc[k][j];
以後每次加入乙個新的頂點都要看其與其鄰接點的邊上的權值是否要小於lowcost陣列中對應頂點的權值。如果小於就修改
然後找到lowcost陣列中最小的權值 並將其與頂點輸出
普利姆演算法
普利姆 prim 這個演算法有什麼用?在實際中這個演算法經常用到電子板的電路連線中,因為可以使用到最少的連線將所有的電子連線起來,又打個比方在鋪設電線將所有使用者連線起來可以使用最少的電線連線起來 知道了這個作用之後你是不是比較感興趣呢?首先看 prim演算法生成最小生成樹 void minispa...
普利姆演算法
演算法思想 可取圖中任意乙個頂點v作為生成樹的根,之後若要往生成樹上新增頂點w,則在頂點v和w之間必定存在一條邊。並且該邊的權值在所有連通頂點v和w之間的邊中取值最小。一般情況下,假設n個頂點分成兩個集合 u 包含已落在生成樹上的結點 和v u 尚未落在生成樹上的頂點 則在所有連通u中頂點和v u中...
普利姆演算法
原理 將頂點分為兩個類,其中一類為沒有選中類,另一類為選中類。每次迭代中將權值小的路徑新增到選中類找到最小生成樹。我們從a點開始,首先將a點納入選中類,在從a點向非選中類找最小路徑得到a b這條,此時再將a和b看為乙個整體,向非選中類找最小路徑得到a b c,按照這種流程最終可以得到最後一幅圖,去掉...