最小生成树算法之Prim算法

2023-11-12

生成树

 一个连通图的生成树是一个极小连通子图,它含有图中全部n个顶点和构成一棵树的(n-1)条边。  
  • 连通图由一次遍历就可以产生生成树
  • 由深度优先遍历得到的生成树称为深度优先生成树。
  • 由广度优先遍历得到的生成树称为广度优先生成树。

一个连通图的生成树不一定是唯一的!

最小生成树

对于带权连通图G (每条边上的权均为大于零的实数),可能有多棵不同生成树。
每棵生成树的所有边的权值之和可能不同。
其中权值之和最小的生成树称为图的最小生成树。

在这里插入图片描述

Prim算法

普里姆(Prim)算法是一种构造性算法,用于构造最小生成树。过程如下:

  1. 初始化U={v}。v到其他顶点的所有边为候选边;
  2. 重复以下步骤n-1次,使得其他n-1个顶点被加入到U中:
  3. 从候选边中挑选权值最小的边输出,设该边在V-U中的顶点是k,将k加入U中;
  4. 考察当前V-U中的所有顶点j,修改候选边:若(j,k)的权值小于原来和顶点k关联的候选边,则用(k,j)取代后者作为候选边。
    在这里插入图片描述

代码

Prim 算法构造生成树

//Prim 算法构造生成树
void Prim(MatGraph g, int v)
{
    int lowcost[MAXV];//存储权值
    int MIN;
    int closest[MAXV], i, j, k;
//closet是用来存储与它相邻的节点的
    for (i = 0; i < g.n; i++)
    {
        lowcost[i] = g.edges[v][i]; //初始化
        closest[i] = v;
    }
    for (i = 1; i < g.n; i++)
    {
        MIN = INF;
        for (j = 0; j < g.n; j++)
            if (lowcost[j] != 0 && lowcost[j] < MIN)
            {
                MIN = lowcost[j];
                k = j; //记录最近的节点的编号
            }
        printf("边(%d,%d)权为:%d\n", closest[k], k, MIN);
        lowcost[k] = 0;

        for (j = 0; j < g.n; j++)
            if (lowcost[j] != 0 && g.edges[k][j] < lowcost[j]) //寻找有没有比较小的边
            {
                lowcost[j] = g.edges[k][j];
                closest[j] = k;
            }
    }
}

测试代码

# include <stdio.h>
# include <stdlib.h>
#define ElemType int
#define maxsize 100
#define InfoType int
#define MAXV 100
#define MaxSize 100
#define INF 214748364 
#define INFINITE INF
//邻接矩阵的数据类型
typedef struct s
{
    int no;     //顶点编号
    InfoType info;//顶点的其他信息
} VertexType;      //顶点的类型

typedef struct SS
{
    int edges[MAXV][MAXV]; //邻接矩阵的数组
    int n, e;              //图的顶点数和边数
    VertexType vexs[MAXV]; //存放顶点信息
} MatGraph;
///

//Prim 算法构造生成树
void Prim(MatGraph g, int v)
{
    int lowcost[MAXV];
    int MIN;
    int closest[MAXV], i, j, k;

    for (i = 0; i < g.n; i++)
    {
        lowcost[i] = g.edges[v][i]; //init
        closest[i] = v;
    }
    for (i = 1; i < g.n; i++)
    {
        MIN = INF;
        for (j = 0; j < g.n; j++)
            if (lowcost[j] != 0 && lowcost[j] < MIN)
            {
                MIN = lowcost[j];
                k = j; //记录最近的节点的编号
            }
        printf("边(%d,%d)权为:%d\n", closest[k], k, MIN);
        lowcost[k] = 0;

        for (j = 0; j < g.n; j++)
            if (lowcost[j] != 0 && g.edges[k][j] < lowcost[j])
            {
                lowcost[j] = g.edges[k][j];
                closest[j] = k;
            }
    }
}
//
void InitMatGraph(MatGraph & g, int a[][MAXV], int n, int e)
{
    int i, j;
    g.n = n;
    g.e = e;
    for(i = 0; i< n; i++)
        for(j = 0; j < n; j++)
            g.edges[i][j] = a[i][j];
}


int main ()
{
    //注意无向带权图i=j是为0
        int a[4][MAXV] = {{0, 1, 3, 1},
                          {1, 0, 2, 4},
                          {3, 2, 0, INF},
                          {1, 4, INF, 0}};
        MatGraph  g;

        InitMatGraph(g, a, 4, 5);

        Prim(g, 0);
        return 0;
}

测试结果
在这里插入图片描述

Enjoy

在这里插入图片描述

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

最小生成树算法之Prim算法 的相关文章

随机推荐

  • C语言----实现有向图/无向图的创建与基本操作(深度、广度优先遍历)

    最近发现一个不错的项目 Github上数据结构所有算法源码实现 数据结构 严蔚敏 吴伟民 教材源码与习题解析 1 图的数组 邻接矩阵 存储表示 包含算法 有向图 无向图创建 添加顶点 删除边 插入边 深度优先遍历 递归 广度优先遍历 队列实
  • 跨平台的桌面应用程序开发框架Electron

    electron electron Stars 109 3k License MIT Electron 是一个基于 Node js 和 Chromium 的开源框架 允许使用 JavaScript HTML 和 CSS 编写跨平台的桌面应用
  • Elasticsearch系列---聚合查询原理

    概要 本篇主要介绍聚合查询的内部原理 正排索引是如何建立的和优化的 fielddata的使用 最后简单介绍了聚合分析时如何选用深度优先和广度优先 正排索引 聚合查询的内部原理是什么 Elastichsearch是用什么样的数据结构去执行聚合
  • linux 下交换 esc与cap的方法。

    有两种方法 1 xmodmap 2 dconf editer 操作如下图所示 xkb options 改为图片所示
  • STM32项目 -- 选题分享(部分)

    前言 分享部分STM32项目选题以及实现效果 暂时没有分享代码 列表 编号 项目名称 难度 使用器件 实现效果 1 基于STM32的智能万用表设计 3 STM32F103C8T6 OLED 1 测量电压 2 OLED显示测量值 3 实现层级
  • ASP.NET-----Repeater数据控件的用法总结

    一 Repeater控件的用法流程及实例 1 首先建立一个网站 新建一个网页index aspx 2 添加或者建立APP Data数据文件 然后将用到的数据库文件放到APP Data文件夹中 3 打开数据库企业管理器 数据库服务器为loca
  • 【帧同步】关于状态同步的经验分享

    方案 低延迟环境下 比如国内 局域网情况下 写个同步那都不是难事 是个客户端看点书就会写了 难点在于 如何去处理 高延迟 以及及时响应的情况 我举个例子 fps或者tank游戏中 子弹和炮弹的射速是很快的 如果两边在对轰过程中 又碰到了 附
  • Qt (ui界面)信号与槽函数 组件连接

    重点 信号与槽连接机制 难点 信号与槽函数的 参数使用 头函数 ifndef WIDGET H define WIDGET H include
  • 登录页面,表单提交,参数不显示

    一开始的form
  • curl下载文件

    我的个人博客 逐步前行STEP curl url o filename progress 下载url的内容到文件filename中 并显示下载进度
  • 深度学习面试八股文(2023.9.06)

    一 优化器 1 SGD是什么 批梯度下降 Batch gradient descent 遍历全部数据集算一次损失函数 计算量开销大 计算速度慢 不支持在线学习 随机梯度下降 Stochastic gradient descent SGD 每
  • 三种常用的排序方法图解及C语言实现(选择排序,冒泡排序,快速排序)

    选择排序 冒泡排序 快速排序 选择排序 选择排序是最简单直观的一种算法 选择排序是不稳定排序 基本思想 首先在未排序序列中找到最小 大 元素 存放到排序序列的起始位置 然后 再从剩余未排序元素中继续寻找最小 大 元素 然后放到已排序序列的末
  • 迷宫 蓝桥杯 602

    题目描述 本题为填空题 只需要算出结果后 在代码中使用输出语句将所填结果输出即可 下图给出了一个迷宫的平面图 其中标记为 1 的为障碍 标记为 0 的为可以通行的地方 010000 000100 001001 110000 迷宫的入口为左上
  • Java中的锁详解说明

    转自 Java中的锁详解说明 下文笔者讲述java中锁的详解 如下所示 java锁简介 锁与synchronized同步块具有同样的功能 是一种线程同步机制 但锁比Java中的synchronized同步块更复杂 因为锁是由synchron
  • 【Fiddler】从零开始学习Fiddler

    文章目录 Fiddler的工作原理 Fiddler的代理模式 1 流模式 Streaming 2 缓冲模式 Buffering Fiddler工具条按钮介绍 如何使用Fiddler抓取https包 如何使用Fiddler抓取手机包 Fidd
  • conda & yaml

    conda导出已有环境 环境会被保存在environment yaml文件中 conda env export gt environment yaml 当我们想再次创建该环境 或根据别人提供的 yaml文件复现环境时 就可以通过下面的命令来
  • tensorflow中tf.keras.models.Sequential()用法

    tensorflow中tf keras models Sequential 用法 Sequential 方法是一个容器 描述了神经网络的网络结构 在Sequential 的输入参数中描述从输入层到输出层的网络结构 model tf kera
  • 第一个实例:QT实现汽车电子仪表盘

    目录 1 实现效果 1 1 视频演示 1 2 实现效果截图 2 生成的安装程序 3 功能概述 4 具体实现 5 QT扩展介绍 5 1 QT介绍 5 2 QT历史发展 5 3 QT平台支持 5 4 Qt Creator 5 5 优势 5 5
  • java.lang.reflect.InvocationTargetException

    产生原因 1 包冲突 有重复包或者缺少包 2 项目jdk和部署jdk版本不一样 导致InvocationTargetException异常信息返回一个空值 没有调用invoc里的重写消息方法 3 映射文件发生改变 对于不同原因的解决 1 包
  • 最小生成树算法之Prim算法

    生成树 一个连通图的生成树是一个极小连通子图 它含有图中全部n个顶点和构成一棵树的 n 1 条边 连通图由一次遍历就可以产生生成树 由深度优先遍历得到的生成树称为深度优先生成树 由广度优先遍历得到的生成树称为广度优先生成树 一个连通图的生成