【算法导论】最小生成树之Kruskal法
在图论中,树是指无回路存在的连通图。一个连通图的生成树是指包含了所有顶点的树。如果把生成树的边的权值总和作为生成树的权,那么权值最小的生成树就称为最小生成树。因为最小生成树在实际中有很多应用,所以我们有必要了解怎样生成最小生成树。构造最小生成树的两种常用方法:Kruskal算法、Prim算法。本文介绍Kruskal算法,Prim算法在下篇文章中介绍。
Kruskal算法是从另一条途径来求网络的的最小生成树。设G=(V, E)是一个有n个顶点的连通图,则令最小生成树的初值状态为只有n个顶点而无任何边的非连通图T=(V, {空集}),此时图中每个顶点自成一个连通分量。按照权值递增的顺序依次选择E中的边,若该边依附于T中两个不同的连通分量,则将此边加入TE中,否则舍去此边而选择下一条代价最小的边,直到T中所有顶点都在同一连通分量上为止。这时的T,便是G的一棵最小生成树。
物理老师曾说过,图像比文字的信息量大得多,这可以从一幅图像和一篇文章所占电脑的存储空间大小明显得出。因此我们可以同下面的图解过程了解Kruskal算法的思想:
在该算法中,每次都要寻找最短边,如果用邻接矩阵实现的话,则需要对整个矩阵扫描一遍,时间复杂度较高,如果采用邻接表的话,由于每条边都被连接两次,使得寻找时间加倍。所以采用如下结构体:
#include<stdio.h>
#define M 8 //边数
#define N 6 //顶点数
//图的存储结构体
typedef struct
{
int startvex,endvex;//边的两个顶点
int length;//边长
int sign;//是否被选择,1表示被选择,0表示未被选择,2表示选择后形成环,被抛弃
}edge;
edge T[M];
int flag1[N];//标记顶点是否已被选中
void Kruskal(edge T[M],int *flag1)
{
int i,j,k,l,min;
int a[M]={0,0,0,1,1,1,2,3,3,4};//边的两个顶点及边的长度
int b[M]={1,4,5,2,3,5,3,4,5,5};
int c[M]={10,19,21,5,6,11,6,18,14,33};
//int a[M]={0,0,0,1,1,2,3,4};//边的两个顶点及边的长度
//int b[M]={1,3,5,2,4,3,4,5};
//int c[M]={7,3,5,6,9,8,4,2};
for(i=0;i<N;i++)
flag1[i]=i;
for(i=0;i<M;i++)//初始化
{
T[i].startvex=a[i];
T[i].endvex=b[i];
T[i].length=c[i];
T[i].sign=0;
}
j=0;
int flag=0;//记录最小边的序号
while(j<N-1)
{
flag=0;
min=10000;
for(i=0;i<M;i++)
{
if(T[i].sign==0)
{
if(T[i].length<min)
{
k=T[i].startvex;
l=T[i].endvex;
flag=i;
min=T[i].length;
}
}
}
T[flag].sign=1;//标记被选中
//printf("k=%d,l=%d: ",k,l);
//printf("\n");
if(flag1[k]==flag1[l])//当边的两个顶点都已经被选择,说明若选择该边就会形成环
{
T[flag].sign=2;//表示抛弃该边
//printf("ok ");
}
else
{
j++;
for(i=0;i<N;i++)
if(flag1[i]==l)
flag1[i]=flag1[k];
}
//for(int ii=0;ii<M;ii++)
// printf(" %d ",T[ii].sign);
//printf("\n\n");
}
}
void main()
{
Kruskal(T,flag1);
for(int i=0;i<M;i++)
printf("%d ",T[i].sign);
printf("\n");
}
程序的结果与上面的图解的结果稍有不同,但是正确的,因为最小生成树有时候是不唯一的。
注:如果程序出错,可能是使用的开发平台版本不同,请点击如下链接: 解释说明
原文:http://blog.csdn.net/tengweitw/article/details/17380353
作者:nineheadedbird
【算法导论】最小生成树之Kruskal法的更多相关文章
- 算法导论--最小生成树(Kruskal和Prim算法)
转载出处:勿在浮沙筑高台http://blog.csdn.net/luoshixian099/article/details/51908175 关于图的几个概念定义: 连通图:在无向图中,若任意两个顶 ...
- 《算法导论》学习总结 — XX.第23章 最小生成树
一.什么叫最小生成树 一个无向连通图G=(V,E),最小生成树就是联结所有顶点的边的权值和最小时的子图T,此时T无回路且连接所有的顶点,所以它必须是棵树. 二.为什么要研究最小生成树问题 <算法 ...
- 23最小生成树之Kruskal算法
图的最优化问题:最小生成树.最短路径 典型的图应用问题 无向连通加权图的最小生成树 有向/无向加权图的最短路径 四个经典算法 Kruskal算法.Prim算法---------------最小生成树 ...
- 1.1.2最小生成树(Kruskal和Prim算法)
部分内容摘自 勿在浮沙筑高台 http://blog.csdn.net/luoshixian099/article/details/51908175 关于图的几个概念定义: 连通图:在无向图中,若任意 ...
- 最小生成树的Kruskal算法实现
最近在复习数据结构,所以想起了之前做的一个最小生成树算法.用Kruskal算法实现的,结合堆排序可以复习回顾数据结构.现在写出来与大家分享. 最小生成树算法思想:书上说的是在一给定的无向图G = (V ...
- Kruskal算法构造最小生成树
Kruskal算法来构造最小生成树,我总结了分为以下步骤: (1)建图,构造Kruskal边集,边集元素应该包括该边的起始顶点.终止顶点.权值: (2)将边集按权值从小到大的顺序进行排序: (3)从小 ...
- Kruskal和Prim算法求最小生成树
Kruskal算法求最小生成树 测试数据: 5 6 0 1 5 0 2 3 1 2 4 2 4 2 2 3 1 1 4 1 输出: 2 3 1 1 4 1 2 4 2 0 2 3 思路:在保证不产生回 ...
- 经典问题----最小生成树(kruskal克鲁斯卡尔贪心算法)
题目简述:假如有一个无向连通图,有n个顶点,有许多(带有权值即长度)边,让你用在其中选n-1条边把这n个顶点连起来,不漏掉任何一个点,然后这n-1条边的权值总和最小,就是最小生成树了,注意,不可绕成圈 ...
- c/c++ 用克鲁斯卡尔(kruskal)算法构造最小生成树
c/c++ 用克鲁斯卡尔(kruskal)算法构造最小生成树 最小生成树(Minimum Cost Spanning Tree)的概念: 假设要在n个城市之间建立公路,则连通n个城市只需要n-1条线路 ...
随机推荐
- Docker的Fig 项目
在你的应用里面添加一个 fig.yml 文件,并指定一些简单的内容,执行 fig up 它就能帮你快速建立起一个容器 快速搭建基于 Docker 的隔离开发环境 使用 Dockerfile 文件指定你 ...
- Docker基本架构
Docker 采用了 C/S架构,包括客户端和服务端. Docker daemon 作为服务端接受来自客户的请求,并处理这些请求(创建.运行.分发容器). 客户端和服务端既可以运行在一个机器上,也可通 ...
- JavaScripy execCommand函数
execCommand函数命令 execCommand方法是执行一个对当前文档,当前选择或者给出范围的命令.处理Html数据时常用如下格式:document.execCommand(sCommand[ ...
- webpack2 配置 示例
// https://github.com/webpack-contrib/extract-text-webpack-plugin var webpack = require("webpac ...
- ARM C C++内存对齐
ARM 系列处理器是 RISC (Reducded Instruction Set Computing)处理器.很多基于ARM的高效代码的程序设计策略都源于RISC 处理器.和很多 RI ...
- 微信小程序基础之input输入框控件
今天主要详写一下微信小程序中的Input输入框控件,输入框在程序中是最常见的,登录,注册,获取搜索框中的内容等等都需要,同时,还需要设置不同样式的输入框,今天的代码中都要相应的使用. input输入框 ...
- ubuntu日志文件管理
众所周知,ubuntu的日志文件会越来越大,需要定期管理 logrotate是个十分有用的工具,它可以自动对日志进行截断(或轮循).压缩以及删除旧的日志文件.例如,你可以设置logrotate,让/v ...
- springMVC源码分析--AbstractDetectingUrlHandlerMapping(五)
上一篇博客springMVC源码分析--AbstractUrlHandlerMapping(三)中我们介绍了AbstractUrlHandlerMapping,主要介绍了一个handlerMap的ur ...
- chromium出现输入密码解锁登录密钥环
chromium出现输入密码解锁登录密钥环 在ubuntu 16.04上安装了Chromium出现对话框,如下所示: 因为密码框截图困难,这个是网上图片. 点取消就可以使用,但是每次都这样很烦,百度后 ...
- gloox配置聊天室
gloox配置聊天室 (金庆的专栏) gloox是XMPP协议的C++客户端库.以下代码测试创建多人聊天室(MUC), 并进行配置.参照gloox中的muc示例代码.gloox代码示例中没有聊天室的配 ...