最小生成树 - Prim 和Kruskal

来源:互联网 发布:软件测试视频教学 编辑:程序博客网 时间:2024/05/23 18:51

最近有些忙,先把最小生成树的代码挂上,有时间将讲解补上。

在这里两个函数:Prim和Kruskal函数,分别是这两个算法的主算法代码。使用的图存储方式是邻接矩阵。

#include<iostream>#include<string.h>#include<queue>using namespace std;#define MAX 100#define INT_MAX 10000#define min(x,y)(x<y?x:y)typedef struct{int matrix[MAX][MAX]; //邻接矩阵int num;// 最大的顶点数}Graph;int InitNode;Graph example; //实例图// 初始化图void initGraph(){int i,j;for(i=0;i<MAX;i++){for(j=0;j<MAX;j++){example.matrix[i][j]=INT_MAX;}}example.num=0;}void createPoint(){int i,j,val;initGraph();while(cin>>i>>j>>val){if(i==0 && j==0) break;example.matrix[i][j]=val;example.matrix[j][i]=val;example.num = max(example.num,i); //这里偷了个懒,我这里假设顶点之间序号是连续的,没有点之间//序号跨很大的情况,如果需要的话,大家可以写一个函数改一下//这里。example.num = max(example.num,j);}}//输出最后的最短路径void printResult(int *from,int *lowcost,int n){cout<<"--------------------------"<<endl;for(int i=1;i<=n;i++){if(i!=InitNode) cout<<from[i]<<"->"<<i<<":"<<lowcost[i]<<endl;}}void Prim(){int *S = new int[example.num+1]; //已选择集合int *lowcost = new int[example.num+1]; //最小权值int *processed = new int[example.num+1]; //记录已选择int *from = new int[example.num+1]; //记录从哪个结点到对应下标点的//数组初始化for(int i=0;i<=example.num;i++){lowcost[i] = INT_MAX;}memset(from,0,sizeof(from));memset(processed,0,sizeof(processed));//将初始点放入集合中int count = 1,NowProPoint = InitNode;S[count]=NowProPoint; processed[NowProPoint]=1;count++;while(count<=example.num){int minval = INT_MAX, minInd = -1;for(int i=1;i<=example.num;i++){if(processed[i]!=1){if(lowcost[i]>example.matrix[NowProPoint][i]){lowcost[i] = example.matrix[NowProPoint][i];from[i] = NowProPoint;}if(minval>lowcost[i]){minval = lowcost[i];minInd = i;}}}S[count]=minInd; processed[minInd]=1;count++;NowProPoint = minInd;//输出lowcost的变化过程cout<<"--------------------------"<<endl;for(int i=1;i<=example.num;i++){cout<<lowcost[i]<<" ";}cout<<endl;}printResult(from,lowcost,example.num);}void kruskal(){//这个kruskal算法使用堆的时间复杂度是o(eloge),但是因为用了邻接矩阵作为存储方式//所以是o(n3)。。int shortPath,x,y;int *processed = new int[example.num+1]; //联通分量//数组初始化for(int i=0;i<=example.num;i++){processed[i]=i;  //一开始每个节点为一个连通分量}int count = 1;cout<<"--------------------------"<<endl;while(count<example.num){shortPath = INT_MAX;x=-1;y=-1;for(int i=1;i<=example.num;i++){for(int j=1;j<=example.num;j++){if(shortPath>example.matrix[i][j] && (processed[i]!=processed[j])){shortPath = example.matrix[i][j];x= i ;y =j;}}}//将两个连通分量合并成一个for(int i=1;i<=example.num;i++){if(processed[i]==processed[x]) processed[i]=processed[y];}count++;//输出最短路径cout<<x<<"->"<<y<<":"<<shortPath<<endl;}}int main(){InitNode =1;createPoint();Prim();kruskal();return 0;}


0 0