算法设计与分析——prim算法

article/2025/10/28 15:11:55

目录

  • 前言
  • 一、算法思想分析
  • 二、算法效率分析
  • 三、算法代码
    • C语言代码
  • 后记

前言

在上一篇文章中,我们聊了聊KMP算法,一个极其高效但又非常难以理解(个人看来)的算法,如果有朋友想要深度讨论,欢迎私信。
本篇我们来聊聊prim算法,我最早接触prim算法已经记不清是数据结构课中还是离散数学课中了,但即便科目不同,prim算法还是那个prim算法。
prim算法是一种用于在连通图中获取最小生成树的算法同样用于获取最小生成树的算法还有Kruskal算法(大家有兴趣同样可以了解了解,但其实二者是比较相似的),prim算法属于贪心算法的一种,至于为什么,或许在分析其过程的时候大家就明白了。
要理解prim算法,大家首先要理解好什么是连通图?什么是最小生成树?这里我们来简单介绍一下,因为这不是我们本次的重点(如果已经有基础的朋友,可以适当跳过)。

  • 什么是连通图?,首先理解什么是图?(这里面的学问其实有点大,所以我说咱们就是简单介绍下哈,本篇文章还是对有基础的朋友较友好,因为对于有基础的朋友,我可能是在废话哈哈哈)简单来说,平面内许多点通过一些路径相互连接(不一定要全部连接),就构成了一个图,而根据这些点之间的路径是否有方向,又分为了无向图和有向图。如下图,分别是一种无向图和有向图。
    无向图和有向图
    那么?什么是连通图呢?简单来说(只能简单来说了,说多了可以另起一篇文章。。。),就是图中的点通过图中的某些路径(带方向的就必须按照方向来)可以抵达任意一个点。最为简单的模型就是一个地区的许多村落之间的通信,如果每个村庄之间都可以达成通信,就是连通的。

  • 最小生成树是什么呢? 连通图中,每条路径都存在一个权值(理解为距离/成本也行吧,但其实不是这么理解的)。从该连通图出发,寻找一个路径数最少,但每个点之间都可达,就是一个生成树了(专业术语是连通无环子图)。生成树不止一个,而所以生成树中权值之和最小的生成树称为最小生成树。

以上是对最小生成树的简单介绍,如果大家想详细了解一下,可查询资料,这些都不是我们本次的重点。如下给出《算法设计与分析基础》中生成树和最小生成树的定义。
生成树和最小生成树定义
如下为一些例子:
在这里插入图片描述

一、算法思想分析

在简单讲解最小生成树的概念后,我们来聊聊prim算法的思想。前面提到过,prim算法是贪心算法的一种,而贪心算法,讲究的就是要极力满足当前最优,这个当前最优正是prim算法的核心思想。
首先,prim算法中存在两个存储空间, 一个用来存放已加入最小生成树的顶点,而另外一个则用来存放还未加入最小生成树中的顶点。 当连通图中所有顶点已放入用于最小生成树的空间中,那么我们最小生成树算法结束!

  • 算法开始,起始顶点可随机找或指定一个。将起始顶点先放入已选顶点集合中
  • 未放入已选顶点集合中查找一条已选顶点集合中所有点最短(或者是权值最小,这里看自己理解了)的路径(说是一条线或许更合适吧)。刚开始的话,我们已选顶点集合只有一个点!而之后我们会将未加入的顶点一个一个加入已选顶点集合,所以这里的条件必须是已选顶点集合中所有点。显然,在我们找到的这条最短(权值最小)路径的两端的顶点,一个肯定属于还未加入最小生成树中的顶点,另一个肯定属于已加入最小生成树的顶点。将还未加入已选顶点集合的那个点,加入已选顶点集合,本轮任务完成。如果需要路径的,可以将路径记录保存下来。
  • 重复第二步,直到所有顶点已加入已选顶点集合,那么,我们的最小生成树就完成了。如果需要计算最小生成树的权值之和,在每一次找到最短路径的时候求一次和即可,需要具体路径的进行标记即可。

接下来,我们举个栗子来做个示范:
在这里插入图片描述
2
3
4
5
6
该例后续代码将会用到,大家可以自行看看该例。

二、算法效率分析

prim算法的具体效率,是与图的顶点和边数都是有关的。《算法设计与分析基础》中是这么分析的:
prim算法分析
以上是一种高级的分析,我们就简单来点吧。
假设总共又n个顶点,那么我肯定有n次比较过程!而在第k次比较过程中,又有n-k个点和另外n-k个顶点相互比较,那么总结起来,那么算法复杂度几乎再n的立方级别。或许有朋友问了,这么算起来,好像也不是很高效哦?n³级别复杂度的确不是很高,但其实prim算法真正效率是介于n²和n³之间的,因为我们如上的分析是一种最坏的情况,就是每个点之间都存在一条路径。
再者,相比于穷举法(也就是蛮力法)来查找最小生成树,prim算法已是大大提升了。《算法设计与分析基础》中这样写到:
prim算法和穷举法比较

三、算法代码

C语言代码

这里我们图的表示用邻接矩阵来表示,具体请看代码极其注释:

/*最小生成树 prim算法 从一个连通图中获取一个最小生成树*/
/*
输入要求:输入一个连通图 存储模式:邻接矩阵表示 0表示不可达  点依次默认命名为a,b,c,d,e,f,g...
例如:n*n数组
6
0 1 0 0 6 5
1 0 1 0 0 4
0 1 0 6 0 4
0 0 6 0 8 5
6 0 0 8 0 2
5 4 4 5 2 0
即为一种输入 实际上为上课讲解时的连通图表示
输出要求: n-1长度数组 包含n-1条路径 ()表示的为m号点到k号点的那条路径 
(1,2) (2,3) (2,6) (6,5) (6,4)
最小生成树权值之和:1+1+4+5+2=13
*/
#include<stdio.h>
#define MAXN 1000
/*二维数组存储 采用邻阶矩阵数据*/
int input[MAXN][MAXN];
int sign[MAXN]= {0}; // 标记sign数组 初始化全为0 ,1表示已经加入已选列表
int prime(int n) {int sum=0; // 最小生成树权值之和 初始值为0/* 默认从第一个点开始 */sign[1]=1;int counter=1; // 计算当前状态已加入最小生成树队列的个数int flagX=-1,flagY=-1,minNodeValue=1000000;while(counter!=n) {flagX=-1,flagY=-1,minNodeValue=1000000; // 每一次都要初始化 /* 每一次循环都是一次贪心 当前局势的一种最优解 */for(int i=1; i<=n; i++) {if(sign[i]==0) continue; // 如果当前为加入队列 直接下一次循环 其实这是一个笨方法for(int j=1; j<=n; j++) {// 在查找下一个连接点时 发现这个连接点已经在里面了(或者为0,即不可达) 我们直接跳过 我能说这是一个笨方法么?但似乎只能这样if(sign[j]==1||input[i][j]==0) continue;if(input[i][j]<minNodeValue){// 更小的一个进行标记flagX=i;flagY=j;minNodeValue=input[i][j]; }}}/* 一轮查找后 */sign[flagY]=1; // 谁该标1 要清楚counter++; // 找到加一 sum+=input[flagX][flagY]; // 这里其实不用担心指针越界 如果是连通图 在一轮查找下来 肯定能找到一个最小的 printf(" (%d,%d) ",flagX,flagY); // 其实我们都知道 flagX flagY 的位置 在这里顺序不重要 }return sum;
}
int main() {/*作为输入的主函数*/int n;printf("请输入邻接矩阵的维度n:"); scanf("%d",&n);printf("邻接矩阵:\n");for(int i=1; i<=n; i++) {for(int j=1; j<=n; j++) {scanf("%d",&input[i][j]);}}/*调用函数*/int sum = prime(n);printf("\n最小生成树权值之和:sum=%d\n",sum);
}

代码中有部分存在取巧,如果大家有任何建议都可私信或留言。

后记

经过一番分析,prim算法的效率似乎是接近n³的,可能偏离了大家的预期。但是一个算法的高效,不是在于它的算法复杂度是多少,而是在于这个算法和解决同样问题的其他算法,相比之下,这个算法是否高效。
简而言之,高效算法是相对的,并不是绝对的。如果在解决最小生成树问题有其他算法比prim算法更为高效,那么那个算法也可以称之为高效算法。
以上只是我的理解,如果大家有其他意见和想法,欢迎留言或私信。


http://chatgpt.dhexx.cn/article/20cN1hPH.shtml

相关文章

计算机算法设计与分析(1-6章 复习笔记)

计算机算法设计与分析 最近发现一些刷题的网站&#xff0c;牛客、力扣&#xff0c;很适合用来熟悉算法和语言知识点。 第1章 算法概述 1.1 算法与程序 算法 是解决问题的一种方法或一个过程。 严格地说&#xff0c;算法是由若干条指令组成的有穷序列&#xff0c;且满足下述4条…

算法设计与分析——概述

概述 算法的概念何为算法算法的五大特征算法设计的基本步骤算法与数据结构 算法分析算法时间复杂度算法空间复杂度渐进符号&#xff08;O、Ω和θ&#xff09; 算法设计工具——STLSTL概述何为STL容器何为STL算法何为STL迭代器 常用STL容器顺序容器关联容器适配器容器 推荐书籍…

算法设计与分析 —— 算法的复杂度分析

什么是算法的复杂度 &#xff08;1&#xff09;算法复杂度即算法所需要的计算机资源 &#xff08;2&#xff09;算法的复杂度可分为算法的时间复杂度 T ( n ) T(n) T(n) 和算法的空间复杂度 S ( n ) S(n) S(n)&#xff0c;其中 n n n 是问题的规模&#xff08;输入大小&am…

算法设计与分析 第一章 基础知识作业1

目录 算法分析题1.1 函数的渐进表达式1.3 证明对于任何实数x和整数a,b,n:1.7 函数渐进阶 算法实现题1.1 统计数字问题1.3 最多约数问题 算法分析题 1.1 函数的渐进表达式 求下列函数的渐近表达式&#xff1a;3n210n; n2/102n; 211/n; logn3; 10log3n 1.3 证明对于任何实数x…

USTC算法设计与分析-总结

《算法设计与分析》是中国科学技术大学计算机专业的研究生学科基础课&#xff0c;黄刘生老师讲概率算法和近似算法&#xff0c;汪炀老师讲分布式算法&#xff0c;因为课程内容繁杂且难度较大&#xff0c;所以结合了上课所做笔记和期末复习总结成思维导图&#xff0c;梳理下思路…

《算法设计与分析基础》第2版

今天开始学习《算法设计与分析基础》这本书&#xff0c;书中提及的算法均会在后续博客实现。 清华大学出版社。

算法设计与分析重点总结

考试题型&#xff1a; 选择 2* 10个 填空2* 10个 简答 3* 4个 程序分析填空 4* 4个 综合&#xff08;代码&#xff09;8* 4个 第一章基础知识 1.算法的定义 算法就是解决问题的方法&#xff0c;是解决某一特定问题的一组有穷指令的序列&#xff0c;是完成一个任务所需要的具…

算法设计与分析基础 第八章谜题

习题8.1 6.切割木棍问题 为下列问题设计一个动态规划算法。已知小木棍的销售价格pi和长度i相关&#xff0c;i1,2&#xff0c;…&#xff0c;n&#xff0c;如何把长度为n的木棍切割为若干根长度为整数的小木棍&#xff0c;使得所获得的总销售价格最大&#xff1f;该算法的时间效…

算法设计与分析基础(三)

算法设计与分析基础(三) 练习题 根据下列函数的增长次数按照从低到高的顺序对他们进行排序。 解答&#xff1a; 解答&#xff1a; 即&#xff0c;该多项式的始终值为ak*n^k,则结论成立。 考虑下面的算法&#xff1a; 算法Mystery(m) //输入:非负整数n S←0 for i←1 to …

算法设计与分析基础

To All Of You&#xff1a; 一个人在接受科技教育时能得到的最珍贵的收获是能够终身受用的通用智能工具。 在讨论算法的书籍中&#xff0c;一般会采用两种方案中的一种&#xff1a; 1.第一种方案是按照问题的类型对算法进行分类。这类教材安排了不同的章节分别讨论排序&…

第一章 算法设计与分析基础知识

系列文章目录 第一章 算法设计与分析基础知识 第二章 算法的分治策略 第三章 算法的动态规划 第四章 算法的贪心法 …… [TOC](这里写目录标题) # 一级目录 ## 二级目录 ### 三级目录 参考教材 《算法设计与分析&#xff08;第2版&#xff09;》是由屈婉玲、刘田、张立昂、王…

算法设计与分析——算法分析基础

算法分析主要是时间复杂度和空间复杂度的两个方面的分析 此处带着问题小预告一把&#xff1a; 时间复杂度&#xff1f;空间复杂度&#xff1f; 大O、大和大分别表示什么&#xff1f; 如何得到递归方程&#xff1f;如何求解递归方程呢&#xff1f; 带着问题来探索吧~ 目录…

算法设计与分析(1)——基础知识

写完 Java 的我又开始对 算法设计与分析 下手了(✿◡‿◡) 内容主要是以 北京大学 屈婉玲老师的 MOOC 视频来写的&#xff0c;视频共是十周的内容&#xff0c;我决定用 五 篇博客完成。 温馨提示&#xff1a;这个课程不仅适用于 算法设计与分析 的学习&#xff0c;也非常适用…

算法设计与分析——算法基础初步了解

算法的概念 算法:一个有计算步骤构成的序列&#xff0c;可以将一组输入值转换成相应的输出值。或可以用例解决一个明确的问题。 问题&#xff1a;输入及相应输出的描述&#xff1a; 算法的特点&#xff1a;确定性、可行性、输入和输出及有穷性。 正确的算法&#xff1b;停机并…

算法设计与分析基础知识

一、算法设计基础 算法是&#xff08;algorithm&#xff09;是对特定问题求解步骤的一种描述&#xff0c;是指令的有限序列。 算法的五个特性&#xff1a; 输入&#xff1a;一个算法可以有零个或多个输入。 输出&#xff1a;一个算法有一个输出或多个输出。 有穷性&#xff08;…

为你的股票绘制趋势图

手里有一点点公司的股票&#xff0c; 拿不准在什么时机抛售&#xff0c; 程序员也没时间天天盯着看&#xff0c;不如动手写个小程序&#xff0c; 把股票趋势每天早上发到邮箱里&#xff0c;用 python 的 pandas, matplotlib 写起来很容易&#xff0c; 几十行代码搞定。 准备环…

用PYTHON画图 看股票/数字货币的趋势分析 带你直观理解指标 K线图

用PYTHON画图 看股票/数字货币的趋势分析 带你直观理解指标 本文章将用PYTHON 画图 以比特币&#xff08;BTC&#xff09;为例 进行画图分析 &#xff08;小白向&#xff09; Pycharm平台编写 所用到的python库 import requests from lxml import etree import math import …

Plotly中绘制三种经典的股票交易图表(含视频讲解)

作者&#xff1a;Lemon 来源&#xff1a;Python数据之道 Plotly中绘制三种经典的 股票交易图表&#xff08;含视频讲解&#xff09; 大家好&#xff0c;我是 Lemon 。 背景 前一段时间&#xff0c; Lemon 发了一期视频&#xff0c;分享了 Plotly 和 Dash 在投资领域的应用案例。…

如何在股票软件画波浪?波浪原理?初级应用画线

如何在股票软件画波浪&#xff1f;波浪原理?初级应用画线 听语音 浏览&#xff1a;1|更新&#xff1a;2018-03-13 10:07|标签&#xff1a;股票 1 2 3 4 5 6 7 分步阅读 波浪理论最主要特征就是它的通用性&#xff0c;在股市中是一个十分重要的技术研究方向&#xff0c;一旦成…

使用Python生成股票K线图

可视化股票数据&#xff0c;这里只做简单的处理&#xff0c;只显示k线图。选取的是海通证券&#xff08;600837&#xff09;2020年1月1日之后150个交易日的数据。这里代码不多&#xff0c;没有封装成方法&#xff0c;代码如下。数据是提前获取的&#xff0c;获取方法见&#xf…