首页 > 编程语言 >C语言Prim算法和Prim-Alternat找最小生成树

C语言Prim算法和Prim-Alternat找最小生成树

时间:2024-06-03 13:29:06浏览次数:28  
标签:Prim Alternat int C语言 v1 v3 v4 权值 v9

文章目录

1、用prim算法求最小生成树

绿色线会标记选过的边

在这里插入图片描述

从v1当作起始点开始,可选择:
(v1,v2)权值为6
(v1,v3)权值为3
(v1,v4)权值为1
从中选择边(v1,v4),最小权值为1
在这里插入图片描述

从v1和v4中选连接边,可选择的边有:
(v1,v2)权值为6
(v1,v3)权值为3
(v4,v3)权值为2
(v4,v5)权值为10
从中选择权值最小为2的边,(v4,v3)
在这里插入图片描述

v1,v4,v3已经被标记不能相互连接,避免产生回路,从v1、v4、v3中可选择的边有:
(v1,v2)权值为6
(v4,v5)权值为10
(v3,v2)权值为2
从中选择权值最小为2的边,(v3,v2)
在这里插入图片描述

从v1,v4,v3,v2中可选择的边有:
(v2,v9)权值为1
(v4,v5)权值为10
从中选择权值最小1的边,(v2,v9)
在这里插入图片描述

从v1,v4,v3,v2,v9中可选边有:
(v4,v5)权值为10
(v9,v5)权值为 6
(v9,v6)权值为 4
(v9,v7)权值为 3
(v9,v8)权值为 2
从中选择权值最小2的边,(v9,v8)
在这里插入图片描述

从v1,v4,v3,v2,v9,v8中可选边有:
(v4,v5)权值为10
(v9,v5)权值为 6
(v9,v6)权值为 4
(v9,v7)权值为 3
(v8,v7)权值为 3
从中有两条权值为3的边,任选一条(v8,v7)
在这里插入图片描述

从v1,v4,v3,v2,v9,v8,v7中可选边有:
(v4,v5)权值为10
(v9,v5)权值为 6
(v9,v6)权值为 4
(v7,v6)权值为 4
从两条权值为4的边,任选一条(v7,v6)
在这里插入图片描述

从v1,v4,v3,v2,v9,v8,v7,v6中可选边有:
(v4,v5)权值为10
(v9,v5)权值为 6
(v6,v5)权值为 2
选择最小权值为2的边(v6,v5)
在这里插入图片描述

v1,v4,v3,v2,v9,v8,v7,v6,v5所有点被标记
最小生成树找到,总权值为17
在这里插入图片描述

C语言Prim算法实现

#include<stdio.h>
#define M 1000//M表示无穷用1000代替
//判断标记点的函数,避免产生回路
int Is(int arr[9], int flag)
{
	int i = 0;
	for (i = 0; i < 9; i++)
	{
		if (arr[i] == flag)
			return 0;
	}
	return 1;
}
int main()
{
	//把上图权值对应值写成邻接阵
	int map[9][9] =
	{
		{M,6,3,1,M,M,M,M,M},
		{6,M,2,M,M,M,M,M,1},
		{3,2,M,2,M,M,M,M,M},
		{1,M,2,M,10,M,M,M,M},
		{M,M,M,10,M,2,M,M,6},
		{M,M,M,M,2,M,4,M,4},
		{M,M,M,M,M,4,M,3,3},
		{M,M,M,M,M,M,3,M,2},
		{M,1,M,M,6,4,3,2,M}
	};

	//存放被标记的点
	int arr[9] = { 1 };//设置初始点为V1,只有V1被标记
	//记录标记个数
	int count = 1;
	//存放权值总和
	int s = 0;
	//循环变量
	int i = 0;
	//记录最小权下标
	int index = 0;
	//记录最小权
	int min = M;
	//记录点
	int doc = 1;

	//循环部分:
	while (1)
	{

		min = M;
		for (i = 0; i < count; i++)
		{
			int j = 0;
			int c = arr[i] - 1;
			for (j = 0; j < 9; j++)
			{
				if (map[c][j] <= min && Is(arr, j + 1))
				{
					doc = c + 1;
					min = map[c][j];
					index = j;
				}
			}
		}
		s += min;
		arr[count++] = index + 1;
		//打印
		printf("V%d --> V%d ", doc, index + 1);
		//所有点被标记,跳出循环
		if (count == 9)
			break;

	}
	printf("\n总权值为:%d\n", s);
	return 0;
}

运行结果:

在这里插入图片描述

2、用Prim-Alternate算法求最小生成树

Prim-Alternate算法是Prim算法的优化
Prim-Alternate算法是只找当前标记点和上一个标记点的邻边
被标记的点不能互相相连

3、C语言Prim-Alternate算法实现

//Prim-Alternate算法
#include<stdio.h>
#define M 1000//M表示无穷用1000代替
//判断标记点的函数,避免产生回路
int Is(int arr[9], int flag)
{
	int i = 0;
	for (i = 0; i < 9; i++)
	{
		if (arr[i] == flag)
			return 0;
	}
	return 1;
}
int main()
{
	//把上图权值对应值写成邻接阵
	int map[9][9] =
	{
		{M,6,3,1,M,M,M,M,M},
		{6,M,2,M,M,M,M,M,1},
		{3,2,M,2,M,M,M,M,M},
		{1,M,2,M,10,M,M,M,M},
		{M,M,M,10,M,2,M,M,6},
		{M,M,M,M,2,M,4,M,4},
		{M,M,M,M,M,4,M,3,3},
		{M,M,M,M,M,M,3,M,2},
		{M,1,M,M,6,4,3,2,M}
	};

	//存放被标记的点
	int arr[9] = { 1 };//设置初始点为V1,V1被标记
	//记录标记个数
	int count = 1;
	//存放权值总和
	int s = 0;
	//循环变量
	int i = 0;
	//记录最小权下标
	int index = 0;
	//记录最小权
	int min = M;
	//记录点
	int doc = 1;

	int c = 0;
	//循环部分:
	while(1)
	{
		
		 min = M;
//每次循环只找两个标记点相邻的边
		for(i=count-2;i< count ;i++)
		{ 
			int j = 0;
			if (count == 1)
				c = arr[0] - 1;
			else
				c = arr[i] - 1;
			for (j = 0; j < 9; j++)
			{
				if (map[c][j] <= min && Is(arr, j + 1))
				{
					doc = c+1;
					min = map[c][j];
					index = j;
				}
			}
		}
		s += min;
		arr[count++] = index + 1;
		//打印
		printf("V%d --> V%d ",doc , index + 1);
		//所有点被标记,跳出循环
		if (count == 9)
			break;		
	}
	printf("\n总权值为:%d\n", s);
	return 0;
}

运行结果:

在这里插入图片描述

标签:Prim,Alternat,int,C语言,v1,v3,v4,权值,v9
From: https://blog.csdn.net/2401_83305953/article/details/139412053

相关文章

  • 解锁C语言扫雷:详细攻略与完整代码解析
    目录一、游戏分析与设计1、功能说明2、界面设计3、数据结构分析4、文件设计结构二、扫雷游戏的代码实现1、逐步讲解1-1、打印菜单选择界面1-2、初始化棋盘1-3、打印棋盘1-4、布置雷1-4、排雷2、完整代码(加详细注释)2-1、game.h2-2、game.c2-3、test.c三、结尾在编......
  • C语言简述
    初识C语言目录初识C语言前言一、C语言是什么?二、第一个C语言程序1.打开vs2022编译器2.创建源文件3.写代码4.main函数5.printf库函数总结前言其实我也不知道该写什么,这个是我第一篇博客,我就讲述一下我自己在课程中所理解到的知识点给大家分享一下。一、C语言是什......
  • C语言简述2
    文章目录前言一、关键字介绍二、字符和ASCCII码表三.字符串和\01.字符串2.\0字符三.转义字符总结前言接这个上一节课知识点讲,我们在上一节已经说了怎么创建第一个C语言程序,现在我们来讲其中一些知识点。一、关键字介绍在C语言中比如if,return,int这些符号被称为......
  • Qt中怎么引用C语言的.c文件?
    Qt窗口项目使用的源文件是.h/.cpp文件,它们是对应C++文件。在实际应用中,你可能有现成的.h/.c文件需要引用。那么,这些文件能够引用吗?又怎么引用呢?以下来讨论这个问题。本例在ubuntu18中Qt5.8.0的Widgets项目编译通过,估计在CentOS和Windows系统也应该可以通过。一般情况下,通过宏“#......
  • Qt中怎么引用C语言的.h文件?
    Qt窗口项目使用的源文件是.h/.cpp文件,它们是对应C++文件。在实际应用中,你可能有现成的.h/.c文件需要引用。那么,这些文件能够引用吗?又怎么引用呢?以下来讨论这个问题。本例在ubuntu18中Qt5.8.0的Widgets项目编译通过,估计在CentOS和Windows系统也应该可以通过。本例要引用的.h文件......
  • 数据结构-单链表操作及代码实现(C语言)
    (一)单链表与线性表支持随机访问的特点相比,单链表的特点是适合插入与删除。结构体定义typedefintElementType;//数据元素类型定义typedefstructLNode//单链表结构体定义{ElementTypedata;//数据域structLNode*next;//存储下一个结点的地址}LNode,*L......
  • 【C语言进阶】--- 动态内存管理
    动态内存管理函数1.malloc函数void*malloc(size_tsize);功能:向堆区的空间中申请一块大小为size个字节的空间,返回指向这块空间的指针如果开辟失败会返回一个NULL指针,因此要检查malloc的返回值,避免返回NULL指针后再访问空指针malloc申请的空间,程序退出后会还给操作系统......
  • 轻松拿捏C语言——【文件操作】
    ......
  • C语言文件操作
    一.文件的先关知识1.1什么是文件?                                                  磁盘上的文件是文件,在程序设计的时候,我们一般将文件分为两种:程序⽂件、数据⽂件(......
  • 【C语言项目实战】使用单链表实现通讯录
                                                                  ......