prime算法
prime算法的思想就是:
设G={V,E}是带权图,V是图G的顶点集,E是边集。
在图中任取一个顶点k作为起始点,令U={k},W=V-U,TE={}(TH为空集),其中W为图中剩余顶点的集合
在有一个U中的顶点,和一个W中的顶点构成 的所有边中,找到一条权值最小的边(u,v),将该边作为最小生成树放入到TE中,并将顶点v加入到集合U中,并从W中删除这个顶点。
重复上一步骤,知道W为空集为止。此时TE中有n-1条边,则T={U,TE}就是G的一颗最小生成树
举例说明:
如图,是一个带权连通图,
首先,确定起始顶点。我以顶点A作为起始点。根据查找法则,与点A相邻的点有点B和点H,比较AB与AH,我们选择点B,如下图。并将点B加入到U中。
继续下一步,此时集合U中有{A,B}两个点,再分别以这两点为起始点,根据查找法则,找到边BC(当有多条边权值相等时,可选任意一条),如下图。并将点C加入到U中。
继续,此时集合U中有{A,B,C}三个点,根据查找法则,我们找到了符合要求的边CI,如下图。并将点I加入到U中。
........
........
.......
#include<iostream>
using namespace std;
#define max 100
#define maxInt 32767
//定义图
typedef struct {
char vexs[100]; //顶点表
int arcs[100][100]; //矩阵
int vexnum; //顶点值
int arcnum; //边值
}AMGraph;
//权值最小边
struct {
char adjvex; //顶点
int lowcost; //权值
}closeedge[100];
//确定位置函数
int LocalVex(AMGraph G, char v)
{
for (int i = 0; i < G.vexnum; i++)
{
if (G.vexs[i] == v)
{
return i;
}
}
return -1;
}
//创建无向图
void CreatUDN(AMGraph & G) {
int i, j, k;
cout << "please input the num of vex and arcs of Graph,seperate them with spece key:" << endl;
cin >> G.vexnum >> G.arcnum; //输入顶点数和边数
cout << endl;
//输入顶点信息
cout << "please input name of vexs as a:" << endl;
for ( i = 0; i < G.vexnum; i++)
{
cout << "please the name of " << (i + 1) << " vex:";
cin >> G.vexs[i];
}
cout << endl;
//输入权值
//初始化
for (i = 0; i < G.vexnum; i++) {
//顶点
for ( j = 0; j < G.vexnum; j++)
{
G.arcs[i][j] = maxInt; //置为最大值
}
}
//边的数量
cout << "please input the vexs of arc and corresponding weight as a b 1:" << endl;
for (k = 0; k < G.arcnum; k++) {
char v1, v2;
int weight;
cout << "please input the vex name and weight of" << (k + 1) << "arc:";
cin >> v1 >> v2 >> weight;
i = LocalVex(G, v1);
j = LocalVex(G, v2);
G.arcs[i][j] = weight; //将权值赋值
G.arcs[i][j] = G.arcs[i][j];
}
}
//权值最小边
int Min(AMGraph G) {
int index = -1;
int min = maxInt;
for (int i = 0; i < G.vexnum; i++) {
if (min > closeedge[i].lowcost && closeedge[i].lowcost != 0) { //找出最小的以及不在同一集合中的
min = closeedge[i].lowcost;
index = i;
}
}
return index;
}
//最小生成树算法
void prime(AMGraph G, char u) {
//先构造起始顶点
int k, i, j;
char u0, v0;
k = LocalVex(G, u);
for (j = 0; j < G.vexnum; j++)
{
if (j != k) {
closeedge[j].adjvex = u;
closeedge[j].lowcost = G.arcs[k][j];
}
}
closeedge[k].lowcost = 0;
for (i = 1; i < G.vexnum; i++)
{
k = Min(G); //找出最短边
u0 = closeedge[k].adjvex; //找出最短边对应的顶点
v0 = G.vexs[k];
cout << "arc " << u0 << "---->" << v0 << endl;
closeedge[k].lowcost = 0;
//更新数组
for (j = 0; j < G.vexnum; j++)
{
if (G.arcs[k][j] < closeedge[j].lowcost)
{
closeedge[j].adjvex = G.vexs[k];
closeedge[j].lowcost = G.arcs[k][j];
}
}
}
}
int main(void) {
AMGraph G;
CreatUDN(G);
prime(G,'a');
return 0;
}