1、基本原理。
<1>、采用一个一维bool数组表示图中所有点是否已经被访问过,初始时均为false。采用一个一维数组表示当前图中的顶点到【当前的最小生成树】的最小的距离。
<2>、初始时,需要选定一个点作为生成最小生成树的起点,那么,首先访问这个顶点,并将当前图中的顶点到当前生成的最小生成树的最小距离初始化为图中顶点到起点的边的权值。
<3>、循环n-1次(n代表图中顶点的数目)。遍历图中所有的顶点,找出一个未访问的且与【当前最小生成树】的距离最小的顶点。纪录这个顶点的编号,并访问之,累计权重。若原始图中存在某些顶点到新加入最小生成树中的这个顶点的距离小于之前的图中的顶点到【之前的最小生成树】的最小的距离。,则更新当前图中的顶点到【当前的最小生成树】的最小的距离。
算法图示:
2、实现。
//假定图中最大顶点个数为5
#define MAX_VERTEX 5
//采用二维数组来表示图
unsigned graph[MAX_VERTEX][MAX_VERTEX]=
{
{(unsigned)-1,1,2,(unsigned)-1,4},
{1,(unsigned)-1,(unsigned)-1,8,2},
{2,(unsigned)-1,(unsigned)-1,(unsigned)-1,6},
{(unsigned)-1,8,(unsigned)-1,(unsigned)-1,3},
{4,2,6,3,(unsigned)-1}
};
bool visited_[MAX_VERTEX];
从顶点编号为nodeID的结点出发构造最小生成树
图采用二维数组来存储,保证图是联通的
int primAlgorithm(unsigned gra[MAX_VERTEX][MAX_VERTEX],int nodeID)
{
unsigned distance[MAX_VERTEX]={(unsigned)-1,
(unsigned)-1,
(unsigned)-1,
(unsigned)-1,
(unsigned)-1};
//更新到各个结点到当前结点的距离
for(int i=0;i<MAX_VERTEX;++i)
{
distance[i]=gra[nodeID][i];
visited_[i]=false;
}
//访问当前顶点
int curVisitedIndex=nodeID;
std::cout<<"current Node has been visited,its Index: "<<curVisitedIndex<<std::endl;
visited_[curVisitedIndex]=true;
int sumCost=0;
for(int i=1;i<MAX_VERTEX;++i)
{
unsigned minDistance=(unsigned)-1;
for(int j=0;j<MAX_VERTEX;++j)
{
//在当前的图中未访问过的结点中距离
if(visited_[j]==false&&distance[j]<minDistance)
{
curVisitedIndex=j;
minDistance=distance[j];
}
}
std::cout<<"current Node has been visited,its Index: "<<curVisitedIndex<<std::endl;
visited_[curVisitedIndex]=true;
sumCost+=minDistance;
for(int i=0;i<MAX_VERTEX;++i)
{
if(visited_[i]==false&&graph[curVisitedIndex][i]<distance[i])
{
distance[i]=graph[curVisitedIndex][i];
}
}
}
return sumCost;
}
//测试函数
int main()
{
int sum=primAlgorithm(graph,1);
std::cout<<"sum Cost:"<<sum<<std::endl;
std::cout<<std::endl;
return 0;
}
3、运行截图。
参考:
[1].https://blog.csdn.net/luoshixian099/article/details/51908175