算法描述:
普利姆算法求最小生成树时候,和边数无关,只和定点的数量相关,所以适合求稠密网的最小生成树,时间复杂度为O(n*n)。
算法过程:
1.将一个图的顶点分为两部分,一部分是最小生成树中的结点(A集合),另一部分是未处理的结点(B集合)。
2.首先选择一个结点,将这个结点加入A中,然后,对集合A中的顶点遍历,找出A中顶点关联的边权值最小的那个(设为v),将此顶点从B中删除,加入集合A中。
3.递归重复步骤2,直到B集合中的结点为空,结束此过程。
4.A集合中的结点就是由Prime算法得到的最小生成树的结点,依照步骤2的结点连接这些顶点,得到的就是这个图的最小生成树。
图例:
不能转换图片方向。。。。。。
我建议您最好拿草稿纸出来边看边画,代码还蛮长比较费脑。
#include <bits/stdc++.h>
using namespace std;
/**
定义数据结构体
*/
const int M=100;
typedef char Elemtype;
typedef int ElemInt;
typedef struct Graph{
int n; //顶点
int e; //边
//顶点存储
ElemInt vex[M];
//边存储
ElemInt edges[M][M];
}Graph;
/**
查找顶点边在数组中的位置
*/
int search(ElemInt vex[],ElemInt point){
int i=0;
while(i<M){
if(vex[i]==point) {
return i;
}
i++;
}
return -1;
}
/**
(无向图)邻接矩阵的创建
*/
void CreateGraph(Graph &G){
int l,r;
printf("请输入顶点和边的个数\n");
cin>>G.n>>G.e;
printf("请输入%d条顶点\n",G.n);
for(int i=0;i<G.n;i++)
cin>>G.vex[i];
//初始化矩阵(初始值)
for(int i=0;i<G.n;i++)
for(int j=0;j<G.n;j++)
if(i==j)
G.edges[i][j]=0; //对角线
else
G.edges[i][j]=32767;
printf("请输入%d条边的起始和终点位置\n",G.e);
for(int i=0;i<G.e;i++){
int lpoint,rpoint,power;
printf("请输入第%d条边的信息(起始点 终点 权值)\n",i+1);
cin>>lpoint>>rpoint>>power; //输入边的信息和权值
l=search(G.vex,lpoint);
r=search(G.vex,rpoint);
G.edges[l][r]=power; //l--->r
G.edges[r][l]=power; //r--->l
}
}
/**
Prim算法求解最小生成树的算法
*/
void Prim_MinTree(Graph *G){
int min,i,j,k;
int adjvex[M]; //保存相关顶点下标
int lowcost[M]; //保存相关顶点间边的权值
lowcost[0]=0; //初始化边(0,0)权值为0,即v0加入生成树
//lowcost的值修改为0就表示该下标的顶点已经加入生成树
adjvex[0]=0; //选取定点v0为起始顶点
for(i=1;i<G->n;i++){ //循环遍历除v0外全部顶点
lowcost[i]=G->edges[0][i]; //将v0顶点与其邻接点边上的权值存入数据
adjvex[i]=0; //adjvex[]初始化为顶点v0的编号0
}
for(i=1;i<G->n;i++){
min=32767; //初始化最小权值为无穷大
j=1;
k=0;
while(j<G->n){ //遍历全部顶点
if(lowcost[j]!=0&&lowcost[j]<min){
//如果权值w满足0<w<min
min=lowcost[j]; //则让当前权值成为最小值
k=j; //若边的权值修改,将对应顶点下标存入k
}
j++;
}
printf("(%d,%d)",adjvex[k],k); //打印当前顶点边中权值最小的边
lowcost[k]=0; //将当前边中选中的边权值置为0,表明该下标的顶点已加入生成树
for(int j=1;j<G->n;j++){
//依附顶点k的边的权值小于此前尚未加入生成树的边的权值
if(lowcost[j]!=0&&G->edges[k][j]<lowcost[j]){
//则用较小的权值替换lowcost[]中的权值
lowcost[j]=G->edges[k][j];
//并将adjvex[]中对应位置的元素修改为新的依附顶点
adjvex[j]=k;
}
}
}
}
int main(){
Graph G;
CreateGraph(G); //创建矩阵
Prim_MinTree(&G); //prime树(打印坐标)
return 0;
}
字比较多所以直接上图片了,希望我的程序您看完有所收获(不喜勿喷)