一,大致的遍歷過程圖解及過程講解
先從某一點開始尋找與其他邊連接最小的邊
1,如下圖(b)中,A與其它五點中C的距離最短,所以連接AC;
2,圖(c)將AC相比較,看誰與剩下點相連距離較短則替代,
如AB=6,CB=5,所以取CB; AE,AF都不相連,而CE,CF都相連所以取AE,AF;
此時比較AC與其它四點連接中距離最短的,所以連接CF;
3,圖(d)將ACF相比較,看誰與剩下點相連距離較短則其替代,
如AD=5,FD=2,所以取FD;CE=6,FE=6,所以不管還用CE,F點B點無連接
此時比較ACF與其它三點連接中距離最短的,所以連接FD;
4,。。。。。。(按照上面方法進行尋找最小)。
二,實現方法
這種方法除了構造鄰接矩陣所需的結構體和函數之外,新加入一個closedge結構體,數組中每一個頂點代表一個點到A的距離。
包含了對應頂點adjvex和權值lowcost。
3代表頂點D
eg:closedge[3]={A,5} 即代表3位置的頂點到A的距離爲5,即DA=5。
此時若DC=3,則替換原來的A,變成closedge[3]={C,3};
第一步:先構造鄰接矩陣,並賦值,該過程類似於圖的鄰接矩陣儲存法類似。
第二步,先將遍歷開始頂點與其餘所有頂點的權賦值到closedge中,然後進行下面循環。
第三步:找到closedge數組中closedge[I].lowcost中最小的值所對應的位置n(即爲closedge[I].adjvex),然後將的權值lowcost變成0,即代表兩點連接。
第四步:將n與所有點連接的距離與closedge進行對比,如果比closedge小則對應替換。
然後再跳到第二步,進行下次循環,總共循環(頂點數-1)次。
此部分可能寫的不是特別好,但是需要講的都在最上面的圖解裏或者可以看下面運行截圖。
三,實現截圖
如下圖所示:每次遍歷出的closedge即爲每次替換後將要比較並取出最小值的。
四,代碼
#include<iostream>
using namespace std;
#define pointMax 100
#define cloEdge 100
typedef struct Node
{
char adjvex; //在圖中的哪個頂點
int lowcost; //權值
}closeedge[cloEdge];
struct AMgroup
{
char VTchart[pointMax]; //頂點表
int AMchart[pointMax][pointMax]; //鄰接矩陣
int point, vert; //點,邊
};
int AMlocate(AMgroup &A, char x) //找到某一頂點的位置
{
for (int i = 0; i < A.point; i++)
{
if (A.VTchart[i] == x)
{
return i;
break;
}
}
cout << "error;";
return -1;
}
void CreatAM(AMgroup &A) //構造鄰接矩陣
{
cout << "輸入鄰接矩陣頂點數:";
cin >> A.point;
cout << "輸入鄰接矩陣邊數:";
cin >> A.vert;
getchar();
char a[100];
cout << "輸入點的信息:";
gets_s(a);
for (int i = 0; i < A.point; i++) //依次輸入點的信息
{
A.VTchart[i] = a[i];
}
for (int i = 0; i < A.point; i++) //初始換鄰接矩陣,邊的權值均設爲最大
{
for (int j = 0; j < A.point; j++)
{
A.AMchart[i][j] = -1;
}
}
char v1, v2; int len;
for (int i = 1; i <= A.vert; i++) //構造鄰接矩陣
{
cout << "輸入第" << i << "條邊的兩個頂點以及權值:";
cin >> v1 >> v2 >> len;
int m, n;
m = AMlocate(A, v1);
n = AMlocate(A, v2);
A.AMchart[m][n] = A.AMchart[n][m] = len;
}
}
int k, j;
int Min(AMgroup &A,Node *closeedge)
{
int a = 32767;
int c;
cout << endl;
cout << "closeedge結構體數組遍歷:" << endl;
for (int i = 0; i < j; i++)
{
cout<<A.VTchart[i]<<" "<<closeedge[i].adjvex <<" "<<closeedge[i].lowcost << endl;
if (closeedge[i].lowcost < a && closeedge[i].lowcost>0) //如果closeedge[i].lowcost小於之前遍歷的最小值且未被遍歷
{
a = closeedge[i].lowcost;
c = i;
}
}
return c;
}
void MSTPrim(AMgroup &A, char m) //普利姆算法
{
Node *closeedge = new Node;
k = AMlocate(A, m);
for (j = 0; j < A.point; j++) //賦值
{
closeedge[j] = { m, A.AMchart[k][j] }; //每個點到所求點的距離
}
closeedge[k].lowcost = 0; //自己到自己初始化爲0
char u0, v0;
for (int i = 1; i < A.point; i++)
{
k = Min(A,closeedge); //找到距離該點距離最短的位置
u0 = closeedge[k].adjvex; //最小邊的一個頂點
v0 = A.VTchart[k]; //最小邊的另一個頂點
cout <<k-1<<"點最小。"<<"本次遍歷邊:"<< u0 << "---" << v0 << endl;
closeedge[k].lowcost = 0; //第K個頂點併入
for (j = 0; j < A.point; j++)
{
if ((A.AMchart[k][j] < closeedge[j].lowcost && A.AMchart[k][j]>0)
|| (A.AMchart[k][j]>0 && closeedge[j].lowcost<0)) //新點周圍與遠點周圍進行判斷
{
closeedge[j] = { A.VTchart[k], A.AMchart[k][j] };
}
}
}
}
int main()
{
AMgroup *A = new AMgroup;
CreatAM(*A);
char m;
cout << "輸入開始遍歷的值:";
cin >> m;
MSTPrim(*A, m);
getchar();
return 0;
}