Prim实现最小生成树
2015-10-14 22:39
330 查看
1,什么是最小生成树?
用连通网(图)表示n个城市以及n个城市间可能设置的通信线路,其中网的顶点表示城市,边表示两城市之间的线路,带有权值。对于这样的一个连通网,找n-1条边使得这n个城市连通,这就是一颗生成树,这样的生成树很多,我们要找总的权值最小的树,即为最小生成树。
2,应用背景?
在n个城市间建立耗费经费最小的通信网。
3,存在方法:Prim和Kruskal方法;主要利用了简称为MST的性质:
假设把连通网的顶点分为了两个集合U和V,现在图里有一条最小权值边u->v;其中u存在U集合,v在V集合,那么这条边u->v一定存在于一颗最小生成树中。
4,Prim算法主要是维持一个closeedge数组。
closeedge数组元素包含两个成员;AdjVex和lowcost;表示的意思是在非i结点所在集合中和i连边的顶点中,权值最小的顶点以及该边权值。
(1)选一个顶点作为开始结点,把顶点集合分成两个集合U和V-U(这里V表示图的所有顶点集合)。初始化closeedge数组;
(2)从closeedge中选一个权值最小的出来,把该顶点归入U;更新closeedge数组;
重复上述操作即可。
测试数据test.txt为:
6 10
0 1 6
0 2 1
0 3 5
1 2 5
1 4 3
2 3 5
2 4 6
2 5 4
3 5 2
4 5 6
输出结果为:
Prim算法的时间复杂度为O(n2);所以它适合求边稠密的网的最小生成树。空间复杂度为O(n),个人理解主要就是维持closeedge数组。
用连通网(图)表示n个城市以及n个城市间可能设置的通信线路,其中网的顶点表示城市,边表示两城市之间的线路,带有权值。对于这样的一个连通网,找n-1条边使得这n个城市连通,这就是一颗生成树,这样的生成树很多,我们要找总的权值最小的树,即为最小生成树。
2,应用背景?
在n个城市间建立耗费经费最小的通信网。
3,存在方法:Prim和Kruskal方法;主要利用了简称为MST的性质:
假设把连通网的顶点分为了两个集合U和V,现在图里有一条最小权值边u->v;其中u存在U集合,v在V集合,那么这条边u->v一定存在于一颗最小生成树中。
4,Prim算法主要是维持一个closeedge数组。
closeedge数组元素包含两个成员;AdjVex和lowcost;表示的意思是在非i结点所在集合中和i连边的顶点中,权值最小的顶点以及该边权值。
(1)选一个顶点作为开始结点,把顶点集合分成两个集合U和V-U(这里V表示图的所有顶点集合)。初始化closeedge数组;
(2)从closeedge中选一个权值最小的出来,把该顶点归入U;更新closeedge数组;
重复上述操作即可。
#include "stdafx.h" #include <fstream> #include <iostream> using namespace std; typedef int ValType; typedef int Vertextype; #define Max_Value 1000 //用在FindMinLowcost函数中 #define INFINITY 65535 //用来初始化邻接矩阵为无穷大 #define path "F:\\test.txt" typedef struct UDG{ int vernum,arcnum; ValType **AdjMatix;//邻接矩阵 }Graph; typedef struct node{ Vertextype AdjVex;//closeedge数组元素中的邻接点 ValType lowcost;//权值 node() { lowcost = 0; } }node;//closeedge数组元素类型 void Readfile(Graph &g)//结果是生成邻接矩阵,读取顶点数和边数 { ifstream infile(path); cout<<"输出顶点数和边数!"<<endl infile="">> g.vernum >> g.arcnum; cout << g.vernum << ' ' << g.arcnum << endl; g.AdjMatix = new ValType*[g.vernum]; int i = 0; for(i;i < g.vernum;i ++) { g.AdjMatix[i] = new ValType[g.vernum]; //memset(g.AdjMatix[i],-1,sizeof(ValType)*g.vernum);//初始化邻接矩阵为无边时的值 for(int t = 0; t < g.vernum; t++) { g.AdjMatix[i][t] = INFINITY; } } cout<<"读取每一条边以及权值!"<<endl; int head,tail,val; int j = 0; for(j; j < g.arcnum; j++) { infile >> head >> tail >> val; g.AdjMatix[head][tail] = val; g.AdjMatix[tail][head] = val; } } int FindMinLowcost(node *x,int length) { int i = 0; int min = Max_Value; int locate; for (i; i < length; i++) { if ((x[i].lowcost != 0) && (x[i].lowcost != INFINITY) && (x[i].lowcost < min)) { min = x[i].lowcost; locate = i; } } return locate; } void MiniSpanTree_Prim(Graph g,Vertextype v)//Prim求最小生成树,关键维持一个closeedge数组 { node *closeedge = new node[g.vernum]; cout << "初始化closeedge数组!" << endl; int j = 0; for (j; j < g.vernum; j++) { if(j != v) { //closeedge[j] = { v, g.AdjMatix[j][v] }; closeedge[j].AdjVex = v; closeedge[j].lowcost = g.AdjMatix[j][v]; } } //closeedge[v].lowcost = 0;//这个语句可以不要,因为lowcost初始化时就为0 int i = 1,k; for (i; i < g.vernum; i++)//只需在V-U中再依次找n-1个顶点 { k = FindMinLowcost(closeedge, g.vernum);//在closedege中找到当前最小lowcost所在位置 cout << closeedge[k].AdjVex << "-->" << k << endl; v = k; closeedge[k].lowcost = 0;//相当于把顶点k放到U中 for (int s = 0; s < g.vernum; s++)//更新closeedge数组,s要在这里定义, { if (closeedge[s].lowcost != 0 && g.AdjMatix[s][k] < closeedge[s].lowcost) { //closeedge[s] = {k, g.AdjMatix[s][k]}; closeedge[s].AdjVex = k; closeedge[s].lowcost = g.AdjMatix[s][k]; } } } } void deletegraph(Graph &g) { int i = 0; for (i; i < g.vernum; i++) { delete []g.AdjMatix[i]; } delete []g.AdjMatix; g.AdjMatix = NULL; } int _tmain(int argc, _TCHAR* argv[]) { Graph A; Readfile(A); MiniSpanTree_Prim(A, 0); deletegraph(A); system("pause"); return 0; } </endl></iostream></fstream>
测试数据test.txt为:
6 10
0 1 6
0 2 1
0 3 5
1 2 5
1 4 3
2 3 5
2 4 6
2 5 4
3 5 2
4 5 6
输出结果为:
Prim算法的时间复杂度为O(n2);所以它适合求边稠密的网的最小生成树。空间复杂度为O(n),个人理解主要就是维持closeedge数组。
相关文章推荐
- 九度OJ 1008:最短路径问题 (最短路)
- Fragment与ViewPager嵌套的简单应用
- android关于获取SD卡手机内存的容量
- x86汇编指令整理
- Java反射
- MVC框架 - 异常处理
- 九度OJ 1008:最短路径问题 (最短路)
- null pointer at org.springframework.beans.PropertyEditorRegistrySupport
- sprintf——把数据写入字符串中
- 【特种兵Excel教程】如何用Excel制作数据透视表?
- Netty使用Http上传文件
- 51nod 1179 最大的最大公约数 (好题!!!!)
- 《大道至简》第三章读后感
- javascript window.onload $(document).ready()
- 给出 《java学习笔记》 PDF格式
- A Smart PostgreSQL extension plproxy 2.2 practices
- 黑马程序员一一高级开发工具Eclipse
- Lock与synchronized 的区别
- Spring 容器初始化方法
- MVC框架 - 捆绑