prime算法---普林姆算法---12月16日

30 篇文章 0 订阅
订阅专栏
本文介绍了Prim算法,一种从起始点开始逐步构建最小生成树的图论算法。通过优先选择与当前顶点相连的最小权重边,直至所有顶点加入。通过实例展示了如何在模板类`MinSpanTree`中实现Prim算法,并提供了关键函数如插入边、输出树结构等。
摘要由CSDN通过智能技术生成

prime算法

  1. 从端点入手
    每一次选一个端点放入生成树中,(保证没有回路,即该点之前没有加入到生成树中)

  2. 若把点加入到生成树中,则需要标记该邻接矩阵的对角线为1.

  3. 如果所有的对角线都为1, 则生成完毕。这里可以用一个计数器来记录。

在这里插入图片描述

1.找所有与u邻接的点,存入权值到最小堆。

2.选一个v点与u点连接最小

3.直到所有点被遍历过

minspantree.h

#include"Graphms.h"
#include"UFsets.h"
#include"Queue.h"
#include <iostream>
const double maxValue = 99999.0;  	//机器可表示的、问题中不可能出现的大数
const int DefaultSize2 = 50;

//最小生成树的类定义(用数组存)
template <typename T, typename E>
class MinSpanTree {
protected:
	MSTEdgeNode<T, E>* edgevalue;			//用边值数组表示树
	int maxSize, currentSize;							//数组的最大元素个数和当前个数
public:
	MinSpanTree(int sz = DefaultSize2 ) {
		maxSize = sz;
		currentSize = 0;
		edgevalue = new MSTEdgeNode<T, E>[sz];
		//assert(edgevalue);
	}
	bool Kruscal(Graphmtx<T, E>& G); // Kruscal算法
	bool Insert(MSTEdgeNode<T, E>& item);	//将边item插入到树中,若树中节点已满,则返回false;
	void output(Graphmtx<T, E>& G);							//自定义函数,顺序输出所有边
	void printMST(Graphmtx<T, E>& G,int n);
	void Prim(Graphmtx<T, E>& G,const T u0, MinSpanTree<T, E>& MST);
};
template<class T, class E>
bool MinSpanTree<T, E>::Insert(MSTEdgeNode<T, E>& item) {
	if (currentSize == maxSize) {
		return false;
	}
	edgevalue[currentSize] = item;
	currentSize++;
	return true;
}

template<class T, class E>
void MinSpanTree<T, E>::output(Graphmtx<T, E>& G) {
	for (int i = 1; i <= currentSize; i++) {
		cout << "Edge " << i << " : " << "head = " << edgevalue[i - 1].head << " ; tail = " << edgevalue[i - 1].tail << " ; key = " << edgevalue[i - 1].key << endl;
		cout << "  点  " << G.getVertical(edgevalue[i - 1].head) << " 到   点" << G.getVertical(edgevalue[i - 1].tail) << " 权重是 " << edgevalue[i - 1].key << endl;
	}
}

template<class T, class E>
bool MinSpanTree<T, E>::Kruscal(Graphmtx<T, E>& G)
{
	MSTEdgeNode<T, E> ed;                    // 边结点辅助单元
	int u=0, v=0, count=0;
	int n = G.NumberofVertices();            // 图的顶点数
	E weight;               // 权值
	MinHeap<T,MSTEdgeNode<T, E>> H(n);       //最小堆存边集及权重信息
	UFSets F(n);     //并查集
	//把图的已知数据输入到最小堆中,插入之后就容易找到最小的数据
	for (u = 0; u < n; u++)
	{
		for (v = u + 1; v < n; v++)  //找该顶点的下一个与之有边的顶点
		{
			weight = G.getWeight(v,u);  //获得权重
			if (weight > 0 && weight < G.maxWeightG)
			{
				ed.head = u;
				ed.tail = v;
				ed.key = weight;
				H.Insert(ed);//插入最小堆中
			}
		}
	}
	count = 1;
	while (count < n && !H.IsEmpty())
	{
		H.RemoveMin(ed);   //找出最小的边
		u = F.Find(ed.tail);//在找的第一遍,是父节点就是自己,就返回自己数组下标。
		v = F.Find(ed.head);
		if (u != v) //当两个根不同时,进行合并。
		{
			F.SimpleUnion(u, v);  //集合合并,连通,连n-1次
			Insert(ed);  //插入到最小生成树中
		    cout<<" 点"<<G.getVertical(ed.tail)<<"到  点"<< G.getVertical(ed.head)<< " 权重是 "<<ed.key<<endl;
			count++;
		}
	}
	if (count < n)
	{
		cout << "不连通,无法生成最小生成树" << endl;
		return false;
	}

	cout << "输出最小生成树" << endl;
	output(G);

	return true;
}

//非成员函数
//prime算法
//u0表示起始点(例如‘A’)
template <class T, class E>
void MinSpanTree<T, E>::Prim(Graphmtx<T, E>& G, const T u0, MinSpanTree<T, E>& MST)
{
	MSTEdgeNode<T, E> ed;
	int i = 0, v = 0, count = 0;
	int n = G.NumberofVertices();          //顶点的数量
	int m = G.NumberofEdges();            //边的数量
	int u = G.getVertexPos(u0);           //取顶点对应的下标值。
	MinHeap<E, MSTEdgeNode<T, E>> H(m); //存边的最小堆
	G.putEdge(u);  //起点标记
	count = 1;
	do
	{
		v = G.getFirstNeighbor(u);   //找到与u 最近的邻接点
		//找所有与u邻接的点,存入权值到最小堆。
		while (v != -1)
		{
			if (G.outEdge(v)==0)
			{
				ed.tail = u; //起点
				ed.head = v;  //终点
				ed.key = G.getWeight(u, v);
				H.Insert(ed);
			}
			v = G.getNextNeighbor(u, v);  //把v传入的原因是需要找在v 之后的邻接点,之前的已经找过了
		}

		//选一个v点与u点连接最小
		while (H.IsEmpty() == false && count < n)
		{
			H.RemoveMin(ed);
			if (G.outEdge(ed.head) == 0)
			{
				MST.Insert(ed);
				u = ed.head;  //用新的头作为起点,找其他与他最近的点
				G.putEdge(ed.head);
				count++;
				break;  //这里找到一个就可以了,重新用新的u 找下一个
			}
		}
	} while (count < n);

	cout << "输出最小生成树" << endl;
	MST.printMST(G,n);
	
}


// 打印最小生成树
template <class T, class E>
void MinSpanTree<T, E>::printMST(Graphmtx<T, E>& G,int n) {
	int tail, head; // 顶点所在位置
	T e1, e2; // 两顶点
	E weight; //  权值
	currentSize = n-1;
	for (int i = 0; i < currentSize; i++) {
		tail = edgevalue[i].tail; // 顶点所在位置
		head = edgevalue[i].head;
		e1 = G.getValue(tail); // 根据位置,取顶点对应的值
		e2 = G.getValue(head);
		weight = G.getWeight(tail, head); // 取权值
		cout << "(" << e1 << "," << e2 << "," << weight << ")" << endl;
	}
}



贪心算法——普林姆算法(Greedy Algorithm-Prim's Algorithm)
UoM_XiaoShuaiShuai的博客
05-31 2804
贪心算法——普林姆算法(Greedy Algorithm-Prim’s Algorithm)贪心算法简介(Introduction of Greedy Algorithm) (pic: https://www.sicas.cn/Students/Info/Content_110622143056742.shtml)There is a common situation in which a c
图的 最小生成树算法 原理简介:Prim’s algorithm and Kruskal’s algorithm
qq_31534103的博客
03-26 4433
文章目录GraphMinimum Spanning Tree(最小生成树))生成算法1. Prim's algorithm( 普林演算法 )实现与 Dijkstra 的差异2.Kruskal's algorithm(克鲁斯卡尔算法)实现 Graph Minimum Spanning Tree(最小生成树)) 定义:For an undirected graph G,is a tree formed...
最小生成树详细讲解(Prime算法+Kruskalsuanfa)
热门推荐
innocence的博客
04-17 1万+
生成树 一个连通图(如果图中任意两点都是连通的,那么图被称作连通图。如果此图是有向图,则称为强连通图(注意:需要双向都有路径))的生成树是该连通图的一个极小连同子图,它含有图中全部顶点,和构成一棵树的(n-1)条边.如果在一棵生成树上添加任何一条边,必定构成一个环,因为这条边使得它依附的那两个顶点之间有了第二条路径.一棵有n个顶点的生成树(连通无回路图)有且仅有(n-1)条边,但是...
最小生成树 (Prime算法+Kruskal算法
Eagle222的博客
08-12 603
Prime算法: [关于算法的过程演示:] (https://blog.csdn.net/lqcsp/article/details/14118871)
最小生成树—prime算法
weixin_46157720的博客
04-11 1万+
生成树 一个连通图的生成树是该连通图的一个极小连同子图,它含有图中全部顶点,和构成一棵树的(n-1)条边。 如果在一棵生成树上添加任何一条边,必定构成一个环,因为这条边使得它依附的那两个顶点之间有了第二条路径。 一棵有n个顶点的生成树(连通无回路图)有且仅有(n-1)条边,但是,有(n-1)条边的图不一定都是生成树。如果一个图有n个顶点和小于(n-1)条边,则是非连通图;如果它有多于(n-1)条边,则一定有回路。 如果图中任意两点都是连通的,那么图被称作连通图。 如果此图是有向图,且双向都有路径,则称为强
图论」最小生成树-Prime算法
说自己行就行
09-17 960
Prim算法 1.概览 普里姆算法(Prim算法),图论中的一种算法,可在加权连通图里搜索最小生成树。意即由此算法搜索到的边子集所构成的树中,不但包括了连通图里的所有顶点(英语:Vertex (graph theory)),且其所有边的权值之和亦为最小。该算法于1930年由捷克数学家沃伊捷赫·亚尔尼克(英语:Vojtěch Jarník)发现;并在1957年由美国计算机科学家罗
【C语言—最小生成树】普里姆(Prime)算法和克鲁斯卡尔(Kruskal)算法
weixin_44348253的博客
10-29 1236
对比两个算法,克鲁斯卡尔算法主要是针对边来展开,边数少时效率会非常高,所以对于稀疏图有很大的优势;而普里姆算法对于稠密图,即边数非常多的情况会更好一些。
ApophisAndroid:Never-Die-Zombieroid :comet::woman_vampire:
05-27
SOPT 2717APP-JAM:Apophis :shooting_star: :pushpin: 部分会议 每天晚上7:30 :artist_palette: 看板 :wrench: 工具 Android Studio 策普林 菲格玛 :victory_hand: 交流工具 概念 松弛 收集 飞涨 :...
storybook-zeplin:Storybook插件,可在故事面板中查看Zeplin资源
02-03
故事书-齐普林 插件,可将Zeplin资源(例如屏幕和组件)嵌入插件面板中,以实现更好的设计开发工作流程。 要求 故事书@> = 5.0.0 该插件应与任何框架一起使用。 如果您发现该插件无效的情况,请打开一个问题。 入门...
数学建模培训-第二轮-李普林.zip
08-03
数学建模培训-第二轮-李普林.zip
数据结构算法之最小生成树-普林算法(Prim)/克鲁斯卡尔算法(Kruskal)
chenliguan的博客
10-17 3953
1 问题提出1.1 一个公司计划建立一个通信网络来连接它的一个计算机中心。可以用租用的电话线连接这些中心的任何一对。应当妊娠瘙痒哪些连接,以便保证在任何两个计算机中心之间都有通路,且网络的总成本最小?可以用下较长所示的带权图为这个问题建模,其中顶点表示计算机中心,边表示可能租用的电话线,边上的权是边所表示的电话线的租费。通过找出一棵生成树,使得这棵树的各边的权之和为最小,就可以解决这个问题。这样的
Javascript算法——双指针法移除元素、数组去重、比较含退格字符、有序数组平方
警警的博客
10-17 517
暴力求解法(两层for循环),length单词拼写错误❌二次嵌套for的length设置。return位置❌ ,核心基础。双指针法(一层for循环)
二分查找算法(折半查找算法
最新发布
Mooczx的博客
10-20 382
是一种在有序数组中查找特定元素的搜索算法。该算法通过将数组分成两半,逐步缩小查找范围来提高查找效率。具体来说,每次比较中间元素与目标值,根据比较结果决定是继续在左半部分还是右半部分进行查找,从而每次迭代都能排除一半的查找空间,时间复杂度对数级别O(logn)
算法】深入了解 CRC 校验码的计算过程
qq_20623849的博客
10-16 618
CRC(循环冗余校验,Cyclic Redundancy Check)是一种常见的错误检测方法,它通过生成冗余码来确保数据传输的可靠性。在这篇文章中,我们将探讨 CRC 码的基本原理,并详细介绍其计算过程。通过对数据进行 CRC 校验,我们可以在传输过程中检测到潜在的错误并采取适当的纠正措施。这个新的数据包在传输时,如果接收方再次计算 CRC 校验码并与附带的校验码进行比较,可以确定数据是否在传输过程中出现了错误。:将附加了零位的数据通过生成多项式进行二进制除法运算,得出的余数就是 CRC 校验码。
【LeetCode每一题】——523.连续的子数组和
IronmanJay的博客
10-17 732
给你一个整数数组 nums 和一个整数 k ,如果 nums 有一个 好的子数组 返回 true ,否则返回 false: 一个 好的子数组 是: 长度 至少为 2 ,且 子数组元素总和为 k 的倍数。 注意: 子数组 是数组中 连续 的部分。 如果存在一个整数 n ,令整数 x 符合 x = n * k ,则称 x 是 k 的一个倍数。0 始终 视为 k 的一个倍数。
【LeetCode热题100】分治-归并
qq_48460693的博客
10-20 444
分治-排序
专题:数组(已完结)
qq_23923713的博客
10-15 265
数组
普林姆算法给出C语言生成代码并附上注释
03-07
普林姆算法是一种用于解决最小生成树问题的算法,其基本思想是从一个随机的节点开始,不断向周围的节点扩展,直到所有节点都被覆盖。以下是 C 语言生成代码并附上注释: // 定义一个邻接矩阵来表示图 int graph[V]...
写文章

热门文章

  • python-4--元组 8932
  • 数据库关系模型与关系运算---2022.2.13 5071
  • SSD学习笔记---2022年3月23日 3642
  • 九宫幻卡(50分) 3505
  • 正则表达式转NFA,DFA,最小化DFA 3279

分类专栏

  • 数据结构 30篇
  • 编译原理 8篇
  • 算法 26篇
  • linux
  • C++ 1篇
  • CSP备战刷题篇 2篇
  • 数据库 2篇

最新评论

  • 蓝桥杯2023年第十四届省赛真题python A组 (个人的做题记录,没有全对,可以通过部分测试点)

    stubborn757: 能不能问一下博主最后拿了什么奖表情包

  • 正则表达式转NFA,DFA,最小化DFA

    smile_keep looking: 有的,私聊给

  • 语法分析---(LL,LR)

    smile_keep looking: 期末复习笔记(^~^)📝,手写版。包括手写代码,有需要私我

  • 语言和文法的形式定义---编译原理

    smile_keep looking: 期末复习笔记(^~^)📝,手写版。包括手写代码,有需要私我

  • 6&8. 语义分析和中间代码生成

    smile_keep looking: 过期末不难啦

最新文章

  • 数据结构期末急救版本
  • 编译原理手写版笔记
  • 基础算法(一)——补
2023年15篇
2022年56篇
2021年49篇

目录

目录

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值

玻璃钢生产厂家武汉佛像玻璃钢雕塑销售电话玻璃钢雕塑断裂商场美陈装饰吊顶道具玻璃钢酒坛雕塑图片玻璃钢 沈阳艾立特雕塑陇南玻璃钢雕塑报价泡沫雕塑好还是玻璃钢渑池玻璃钢雕塑费用上海欧式玻璃钢雕塑优势商场彩灯美陈开阳玻璃钢雕塑定做电话河南通道商场美陈厂家供应玻璃钢不倒翁雕塑贺州玻璃钢雕塑小品民权定做玻璃钢雕塑厂电话小矮人和玻璃钢雕塑中国玻璃钢雕塑生产基地乌海玻璃钢动物雕塑泰州玻璃钢仿铜雕塑商家南平玻璃钢花盆报价上海开业商场美陈销售企业兴化玻璃钢雕塑联系方式永州市玻璃钢雕塑江西户内玻璃钢雕塑生产厂家巴彦玻璃钢雕塑厂甘肃学校玻璃钢园林艺术雕塑商场美陈布置文案天津玻璃钢雕塑厂招聘佛像玻璃钢卡通雕塑设计厂家购置玻璃钢音符雕塑香港通过《维护国家安全条例》两大学生合买彩票中奖一人不认账让美丽中国“从细节出发”19岁小伙救下5人后溺亡 多方发声单亲妈妈陷入热恋 14岁儿子报警汪小菲曝离婚始末遭遇山火的松茸之乡雅江山火三名扑火人员牺牲系谣言何赛飞追着代拍打萧美琴窜访捷克 外交部回应卫健委通报少年有偿捐血浆16次猝死手机成瘾是影响睡眠质量重要因素高校汽车撞人致3死16伤 司机系学生315晚会后胖东来又人满为患了小米汽车超级工厂正式揭幕中国拥有亿元资产的家庭达13.3万户周杰伦一审败诉网易男孩8年未见母亲被告知被遗忘许家印被限制高消费饲养员用铁锨驱打大熊猫被辞退男子被猫抓伤后确诊“猫抓病”特朗普无法缴纳4.54亿美元罚金倪萍分享减重40斤方法联合利华开始重组张家界的山上“长”满了韩国人?张立群任西安交通大学校长杨倩无缘巴黎奥运“重生之我在北大当嫡校长”黑马情侣提车了专访95后高颜值猪保姆考生莫言也上北大硕士复试名单了网友洛杉矶偶遇贾玲专家建议不必谈骨泥色变沉迷短剧的人就像掉进了杀猪盘奥巴马现身唐宁街 黑色着装引猜测七年后宇文玥被薅头发捞上岸事业单位女子向同事水杯投不明物质凯特王妃现身!外出购物视频曝光河南驻马店通报西平中学跳楼事件王树国卸任西安交大校长 师生送别恒大被罚41.75亿到底怎么缴男子被流浪猫绊倒 投喂者赔24万房客欠租失踪 房东直发愁西双版纳热带植物园回应蜉蝣大爆发钱人豪晒法院裁定实锤抄袭外国人感慨凌晨的中国很安全胖东来员工每周单休无小长假白宫:哈马斯三号人物被杀测试车高速逃费 小米:已补缴老人退休金被冒领16年 金额超20万

玻璃钢生产厂家 XML地图 TXT地图 虚拟主机 SEO 网站制作 网站优化