最小生成树Prim算法(邻接矩阵和邻接表)
最小生成树,普利姆算法.
简述算法:
先初始化一棵只有一个顶点的树,以这一顶点开始,找到它的最小权值,将这条边上的令一个顶点添加到树中
再从这棵树中的所有顶点中找到一个最小权值(而且权值的另一顶点不属于这棵树)
重复上一步.直到所有顶点并入树中.
图示:


注:以a点开始,最小权值为1,另一顶点是c,将c加入到最小生成树中.树中 a-c
在最小生成树中的顶点找到一个权值最小且另一顶点不在树中的,最小权值是4,另一个顶点是f,将f并入树中, a-c-f
重复上一步骤,a-c-f-d, a-c-f-d-b, a-c-f-d-b-e.
邻接矩阵的实现
我又构建了一个邻接矩阵(prim_tree),将我们求出的最小生成树写入其中.
我们还需要一个visited数组,来确定一个顶点是否已被纳入最小生成树中.
1)初始化,visited数组,prim_tree节点信息,矩阵.1-11,41-55行
2)将一个顶点并入树(prim_tree)中.以这个顶点开始,进行遍历寻找最小权值.
这里用了三层循环嵌套.
i这一层的作用是遍历图的节点信息,我们要将所有节点都纳入树中.
j这一层的作用是遍历树的节点信息.(我们是通过visited数组来确定一个节点是否属于最小生成树的,19行,if的作用)
k这一层的作用是在j节点所在所在矩阵的行中找到最小权值.
(注:j和k配合,找到树中的最小权值(最小权值的另一个节点没有被纳入树中,23行if的作用).j查找的节点信息的下标,但矩阵是正方形的,所以j既是节点信息的下标,又是该节点在矩阵中的列位置.而k则在j这一列查找最小权值.当j将树遍历一遍,这时会找到一个最小权值,这个最小权值的另一个顶点就是我们将要纳入树中的节点.)
3)将上面获得的信息写入树中.(写入时也要判断该节点是否已被纳入树中.没有纳入树中的节点才会将其纳入树中.)
//最小生成树prim算法
static void init_prim(Graph * graph, Graph * prim_tree);
void Prim(Graph * graph, Graph * prim_tree)
{
bool visited[graph->vertexs];
int i, j, k, h;
int power, power_j, power_k; for ( i = ; i < graph->vertexs; i++ )
visited[i] = false;
init_prim(graph, prim_tree); visited[] = true;
for ( i = ; i < graph->vertexs; i++ )
{
power = MAX_VALUE;
for ( j = ; j < graph->vertexs; j++ )
{
if ( visited[j] )
{
for ( k = ; k < graph->vertexs; k++ )
{
if ( power > graph->arcs[j][k] && !visited[k] )
{
power = graph->arcs[j][k];
power_j = j;
power_k = k;
}
}
}
}
//min power
if ( !visited[power_k] )
{
visited[power_k] = true;
prim_tree->arcs[power_j][power_k] = power;
}
}
} static void init_prim(Graph * graph, Graph * prim_tree)
{
int i, j; prim_tree->vertexs = graph->vertexs;
for ( i = ; i < prim_tree->vertexs; i++ )//初始化节点
prim_tree->vertex[i] = graph->vertex[i];
for ( i = ; i < prim_tree->vertexs; i++ )//初始化矩阵
{
for ( j = ; j < prim_tree->vertexs; j++ )
{
prim_tree->arcs[i][j] = MAX_VALUE;
}
}
}
上述代码适用于连通图.
如果想运行这个程序,到http://www.cnblogs.com/ITgaozy/p/5187483.html找源码,将上面的代码粘到里面就可以了.
邻接表的实现
算法和矩阵一样,只是由于数据结构不同,在代码上有些差别.
static void init_prim(Graph * graph, Graph * prim_tree);
void g_prim(Graph * graph, Graph * prim_tree)
{
bool visited[graph->vertexs];
int i, j, k;
int power, pos;
Arc_node * tmp; for ( i = ; i < graph->vertexs; i++ )
visited[i] = false;
init_prim(graph, prim_tree); visited[] = true;
for ( i = ; i < graph->vertexs; i++ )
{
power = INT_MAX;//limits.h
for ( j = ; j < graph->vertexs; j++ )
{
if ( visited[j] )
{
tmp = graph->adjlist[j].next;
while ( tmp != NULL )
{
if ( power > tmp->distance && !visited[tmp->pos] )
{
power = tmp->distance;
pos = tmp->pos;
k = j;
}
tmp = tmp->next;
}
}
}
if ( !visited[pos] )
{
if ( prim_tree->adjlist[k].next == NULL )
{
prim_tree->adjlist[k].next = make_node(pos, power);
}
else
{
tmp = prim_tree->adjlist[k].next;
while ( tmp->next != NULL )
tmp = tmp->next;
tmp->next = make_node(pos, power);
}
visited[pos] = true;
}
}
} static void init_prim(Graph * graph, Graph * prim_tree)
{
int i; for ( i = ; i < graph->vertexs; i++ )
{
prim_tree->adjlist[i].info = graph->adjlist[i].info;
prim_tree->adjlist[i].next = NULL;
}
prim_tree->vertexs = graph->vertexs;
}
到http://www.cnblogs.com/ITgaozy/p/5187526.html里找到源码,将上述代码粘到源码中,就可以了.
由于本人水平有限,不足之处还望大家不吝指教.
最小生成树Prim算法(邻接矩阵和邻接表)的更多相关文章
- hdoj 2063 过山车【匈牙利算法+邻接矩阵or邻接表】
过山车 Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submiss ...
- 数据结构代码整理(线性表,栈,队列,串,二叉树,图的建立和遍历stl,最小生成树prim算法)。。持续更新中。。。
//归并排序递归方法实现 #include <iostream> #include <cstdio> using namespace std; #define maxn 100 ...
- 图论算法(五)最小生成树Prim算法
最小生成树\(Prim\)算法 我们通常求最小生成树有两种常见的算法--\(Prim\)和\(Kruskal\)算法,今天先总结最小生成树概念和比较简单的\(Prim\)算法 Part 1:最小生成树 ...
- SWUST OJ 1075 求最小生成树(Prim算法)
求最小生成树(Prim算法) 我对提示代码做了简要分析,提示代码大致写了以下几个内容 给了几个基础的工具,邻接表记录图的一个的结构体,记录Prim算法中最近的边的结构体,记录目标边的结构体(始末点,值 ...
- 最小生成树,Prim算法与Kruskal算法,408方向,思路与实现分析
最小生成树,Prim算法与Kruskal算法,408方向,思路与实现分析 最小生成树,老生常谈了,生活中也总会有各种各样的问题,在这里,我来带你一起分析一下这个算法的思路与实现的方式吧~~ 在考研中呢 ...
- PAT1013. Battle Over Cities(邻接矩阵、邻接表分别dfs)
//采用不同的图存储结构结构邻接矩阵.邻接表分别dfs,我想我是寂寞了吧,应该试试并查集,看见可以用并查集的就用dfs,bfs代替......怕了并查集了 //邻接矩阵dfs #include< ...
- 图的存储结构:邻接矩阵(邻接表)&链式前向星
[概念]疏松图&稠密图: 疏松图指,点连接的边不多的图,反之(点连接的边多)则为稠密图. Tips:邻接矩阵与邻接表相比,疏松图多用邻接表,稠密图多用邻接矩阵. 邻接矩阵: 开一个二维数组gr ...
- 最小生成树—prim算法
最小生成树prim算法实现 所谓生成树,就是n个点之间连成n-1条边的图形.而最小生成树,就是权值(两点间直线的值)之和的最小值. 首先,要用二维数组记录点和权值.如上图所示无向图: int map[ ...
- Highways POJ-1751 最小生成树 Prim算法
Highways POJ-1751 最小生成树 Prim算法 题意 有一个N个城市M条路的无向图,给你N个城市的坐标,然后现在该无向图已经有M条边了,问你还需要添加总长为多少的边能使得该无向图连通.输 ...
随机推荐
- 解决企业In-House安装APP需HTTPS支持的问题(转载)
同事写的一篇文章,感觉不错,转过来. 解决企业In-House安装APP需HTTPS支持的问题 问题背景: 能否通过应用服务器发布企业应用: 解决iOS7.1后,发布地址必须为HTTPS服务器. 写作 ...
- MySQL HA方案之MySQL半复制+MHA+Keepalived+Atlas+LVS[转]
MySQL HA方案之MySQL半复制+MHA+Keepalived+Atlas+LVS 简介 目前Mysql高可用的方案有好多,比如MMM,heartbeat+drbd,Cluster等,还有per ...
- cmd窗口编码方式的修改
cmd默认的编码是采用GBK regedit HKEY_CURRENT_USER\Console\%SystemRoot%_system32_cmd.exe\CodePage 十进制:936 GB ...
- Socket模型详解(转)
两种I/O模式 一.选择模型 二.异步选择 三.事件选择 四.重叠I/O模型 五.完成端口模型 五种I/O模型的比较 两种I/O模式 1. 两种I/O模式 阻塞模式:执行I/O操作完成前会一直进行等待 ...
- c# C++接口封装 汽车模拟仿真
struct PinCamParIn//用户输入的针孔相机参数结构体{ char CameraName[512]; float Offset[3]; float Angle[3]; ...
- ubuntu 添加管理员账户
sudo adduser cat 输入密码即可 sudo adduser cat sudo 为cat 添加sudo 权限
- 2^x mod n = 1(欧拉定理,欧拉函数,快速幂乘)
2^x mod n = 1 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Tot ...
- Apache Tomcat关于shtml和SSI技术
Tomcat http://blog.csdn.net/leftfist/article/details/8520773 http://webdevelop.jzxue.com/shtml/ http ...
- ADO.NET 3.5高级编程:应用LINQ&Entity Framework
http://item.jd.com/10080604.html 第1部分 ADO.NET3.5概览第1章 使用ADO.NET3.5提供的新方法访问数据1.1 语言集成查询LINO1.1.1 LIQ ...
- eclipse 手动/自动安装插件
只要你的Eclipse的压缩包,一般为xxx.zip,其内部包含了对应的features和plugins文件夹,(不管是否还有content.jar和artifacts.jar)则都可以: 要么手动解 ...