C++编程练习(10)----“图的最小生成树“(Prim算法、Kruskal算法)
来源:互联网 发布:搜狗大数据 编辑:程序博客网 时间:2024/05/22 16:06
1、Prim 算法
以某顶点为起点,逐步找各顶点上最小权值的边来构建最小生成树。
2、Kruskal 算法
直接寻找最小权值的边来构建最小生成树。
比较:
Kruskal 算法主要是针对边来展开,边数少时效率会非常高,所以对于稀疏图有很大的优势。
Prim 算法针对顶点展开,对于稠密图,即边数非常多的情况下会更好。
具体代码如下:
/* Graph.h头文件 *//*包含图的建立:图的深度优先遍历、图的广度优先遍历*//*包含图的最小生成树:Prim 算法、Kruskal 算法*/#include<iostream>#include"LinkQueue.h"#define MAXVEX 100#define MAXEDGE 100#define INFINITY 65535#define TRUE 1#define FALSE 0typedef char VertexType;typedef int EdgeType;typedef int Boolean;using namespace std;/*邻接矩阵方式建立图*/class MGraph{public:VertexType vexs[MAXVEX];EdgeType arc[MAXVEX][MAXVEX];int numVertexes,numEdges;};/*建立无向网图的邻接矩阵表示*/void CreateMGraph(MGraph *G){int i,j,k,w;cout<<"输入顶点数和边数:"<<endl;cin>>G->numVertexes>>G->numEdges;cin.clear();cout<<"输入顶点信息:"<<endl;for(i=0;i<G->numVertexes;i++){cin>>G->vexs[i];cin.clear();}for(i=0;i<G->numVertexes;i++)for(j=0;j<G->numVertexes;j++){if (i==j)G->arc[i][j]=0;elseG->arc[i][j]=INFINITY;}for(k=0;k<G->numEdges;k++){cout<<"输入边(vi,vj)上的下标i,下标j和权w:"<<endl;cin>>i>>j>>w;cin.clear();G->arc[i][j]=w;G->arc[j][i]=G->arc[i][j];}}/*邻接矩阵的深度优先递归算法*/Boolean visited[MAXVEX];/*访问标志的数组*/void DFS(MGraph G,int i){int j;visited[i]=TRUE;cout<<G.vexs[i];/*打印顶点,也可以其他操作*/for(j=0;j<G.numVertexes;j++)if(G.arc[i][j]==1 && !visited[j])DFS(G,j);/*对为访问的邻接顶点递归调用*/}/*邻接矩阵的深度优先遍历操作*/void DFSTraverse(MGraph G){cout<<"\n深度优先遍历结果为:"<<endl;int i;for(i=0;i<G.numVertexes;i++)visited[i]=FALSE;/*初始化所有顶点状态都是未访问过状态*/for(i=0;i<G.numVertexes;i++)if(!visited[i])/*对未访问过的顶点调用DFS,若是连通图,只会执行一次*/DFS(G,i);cout<<endl;}/*邻接矩阵的广度遍历算法*/void BFSTraverse(MGraph G){cout<<"广度优先遍历结果为:"<<endl;int i,j;LinkQueue Q;for(i=0;i<G.numVertexes;i++)visited[i]=FALSE;for(i=0;i<G.numVertexes;i++){if(!visited[i]){visited[i]=TRUE;cout<<G.vexs[i];Q.EnQueue(i);while(!Q.QueueEmpty()){Q.DeQueue(&i);for(j=0;j<G.numVertexes;j++){if(G.arc[i][j]==1 && !visited[j]){visited[j]=TRUE;cout<<G.vexs[j];Q.EnQueue(j);}}}}}cout<<endl;}/* Prim算法生成最小生成树 */void MiniSpanTree_Prim(MGraph G){cout<<"Prim算法生成最小生成树,结果为:"<<endl;int min,i,j,k;int adjvex[MAXVEX];int lowcost[MAXVEX];lowcost[0]=0;adjvex[0]=0;for(i=1;i<G.numVertexes;i++){lowcost[i]=G.arc[0][i];adjvex[i]=0;}for(i=1;i<G.numVertexes;i++){min=INFINITY;j=1;k=0;while(j<G.numVertexes){if(lowcost[j]!=0 && lowcost[j]<min){min=lowcost[j];k=j;}j++;}cout<<"("<<adjvex[k]<<","<<k<<")"<<endl;lowcost[k]=0;for(j=1;j<G.numVertexes;j++){if(lowcost[j]!=0 && G.arc[k][j]<lowcost[j]){lowcost[j]=G.arc[k][j];adjvex[j]=k;}}}cout<<endl;}/* Kruskal 算法生成最小生成树 */class Edge{/*对边集数组Edge结构的定义*/public:int begin;int end;int weight;};void Swap(Edge *edges,int i,int j)/* 交换权值 以及头和尾 */{int temp;temp=edges[i].begin;edges[i].begin=edges[j].begin;edges[j].begin=temp;temp=edges[i].end;edges[i].end=edges[j].end;edges[j].end=temp;temp=edges[i].weight;edges[i].weight=edges[j].weight;edges[j].weight=temp;}void sort(Edge edges[],MGraph *G)/* 对权值进行排序 */{int i,j;for ( i=0;i<G->numEdges;i++){for ( j=i+1;j<G->numEdges;j++){if (edges[i].weight>edges[j].weight){Swap(edges,i,j);}}}cout<<"权排序之后的为:"<<endl;for (i=0;i<G->numEdges;i++){cout<<"("<<edges[i].begin<<","<<edges[i].end<<")"<<endl;}}int Find(int *parent,int f)/*查找连线顶点的尾部下标*/{while (parent[f]>0)f=parent[f];return f;}void MiniSpanTree_Kruskal(MGraph G){int i,j,n,m;Edge edges[MAXEDGE];int parent[MAXVEX];/*将邻接数组G转化为边集数组edges并按权由小到大排序*******BEGIN*********/int k=0;for ( i=0;i<G.numVertexes-1;i++){for (j=i+1;j<G.numVertexes;j++){if (G.arc[i][j]<INFINITY){edges[k].begin=i;edges[k].end =j;edges[k].weight=G.arc[i][j];k++;}}}sort(edges, &G);/***************END***********************/for (i=0;i<G.numVertexes;i++)parent[i]=0;/* 初始化数组值为0 */cout<<"Kruskal 算法生成最小生成树,结果为:"<<endl;for (i=0;i<G.numEdges;i++)/* 循环每一条边 */{n=Find(parent,edges[i].begin);m=Find(parent,edges[i].end);if (n!=m) /* 假如n与m不等,说明此边没有与现有的生成树形成环路 */{parent[n]=m;/* 将此边的结尾顶点放入下标为起点的parent中。 *//* 表示此顶点已经在生成树集合中 */cout<<"("<<edges[i].begin<<","<<edges[i].end<<") "<<edges[i].weight<<endl;}}}
对于如下所示的图:
运行程序,结果如下:
0 0
- C++编程练习(10)----“图的最小生成树“(Prim算法、Kruskal算法)
- 【算法复习】图的最小生成树(Prim&Kruskal)
- 图的最小生成树:Prim算法和Kruskal算法
- 最小生成树算法(prim&kruskal)
- [C++]最小生成树--Prim算法&Kruskal算法
- 图算法 最小生成树 Prim算法 Kruskal算法
- 最小生成树-Kruskal算法-Prim算法
- 最小生成树 Prim算法 Kruskal算法
- 最小生成树Prim算法Kruskal算法
- 最小生成树Prim算法,Kruskal算法
- 图的应用——最小生成树(Kruskal算法)和(Prim算法)
- 最小生成树的prim算法和kruskal算法
- 关于最小生成树的Prim算法和Kruskal算法
- 【图】最小生成树Prim算法和Kruskal算法
- 图之最小生成树-Prim算法和Kruskal算法
- 最小生成树(prim算法,kruskal算法)
- 最小生成树(Prim算法和Kruskal算法)
- 最小生成树(kruskal算法,prim算法)
- 经典导航栏02,滑动效果,适合做faq或menu
- 网络爬虫系列之二:对下载页面进行链接解析
- 3 种提高编程技能的有趣方法
- 基类与派生类的构造函数调用问题
- Android编程之手绘 ,画图
- C++编程练习(10)----“图的最小生成树“(Prim算法、Kruskal算法)
- MyEclipse8.5自动提示功能的修改
- 棋牌游戏3D化的趋势
- Cracking the coding interview--Q18.1
- Delphi 7下使用Log4Delphi 0.8日志组件
- Boost智能指针——weak_ptr
- ios--OpenCV--图像像素颜色反转
- 开源日志库<log4cplus+VS2008使用>整理
- 用NDK调用第三方动态库--个人总结