首页 > 编程语言 >数据结构图的最短路径-弗洛伊德算法(有向图+数据结构课本C++代码一比一转C语言+邻接矩阵存储结构)-附带图片+终端输入

数据结构图的最短路径-弗洛伊德算法(有向图+数据结构课本C++代码一比一转C语言+邻接矩阵存储结构)-附带图片+终端输入

时间:2024-10-25 16:19:23浏览次数:9  
标签:有向图 Path printf MVNum C++ 权值 顶点 数据结构 输入

弗洛伊德算法有向图代码如下:

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>  
#include <stdlib.h>  
#include<limits.h>
#define MaxInt 32767
#define MVNum 100
int Path[MVNum][MVNum];//存放前驱索引的
int D[MVNum][MVNum];//存放当前已知的权值

//图的邻接矩阵
typedef struct
{
	char vexs[MVNum];
	int arcs[MVNum][MVNum];
	int vexnum, arcnum;
}AMGraph;
int Locate(AMGraph G,char u)
{
	int i;
	for (i = 0; i < G.vexnum; i++)
	{
		if (G.vexs[i] == u)
		{
			return i;
		}
	}
	return -1;
}
void CreateAMGraph(AMGraph* G)
{
	int i, j, k, w;
	printf("请输入顶点数+边数\n");
	scanf("%d %d", &G->vexnum, &G->arcnum);
	getchar();

	printf("请输入顶点信息\n");
	for (i = 0; i < G->vexnum; i++)
	{
		printf("请输入第%d个顶点:", i + 1);
		scanf(" %c", &G->vexs[i]);
	}
	printf("\n");
	for (i = 0; i < G->vexnum; i++)
	{
		for (j = 0; j < G->vexnum; j++)
		{
			if (j!=i)
			{
				G->arcs[i][j] = MaxInt;
			}
			else 
			{
				G->arcs[i][j] = 0;//初始二维数组全部赋极大值,然后j=i的就是自身的,那自身肯定没有权值的,直接给0
			}
		}
	}

	printf("请输入边依附的顶点和权值\n");
	for (k = 0; k < G->arcnum; k++)
	{
		char v1, v2;
		printf("请输入第%d条边依附的顶点和权值:", k + 1);
		scanf(" %c %c %d", &v1, &v2, &w);
		i = Locate(*G, v1);
		j = Locate(*G, v2);
		G->arcs[i][j] = w;//更新arcs二维数组,把有权值的输入替换掉MaxInt
	}
	printf("邻接矩阵有向网创建成功\n");
}
void ShortestPath_Floyed(AMGraph G)
{
	int i, j, k;
	//把G.arcs的二维数组的权值信息先赋给D二维数组
	for (i = 0; i < G.vexnum; i++)
	{
		for (j = 0; j < G.vexnum; j++)
		{
			//D(0)初始状态
			D[i][j] = G.arcs[i][j];
			//Path(0)初始状态
			if (D[i][j] < MaxInt && i!=j)
			{
				Path[i][j] = i;
			}
			else 
			{
				Path[i][j] = -1;
			}
		}
	}
	for (k = 0; k < G.vexnum; k++)
	{
		for (i = 0; i < G.vexnum; i++)
		{
			for (j = 0; j < G.vexnum; j++)
			{
				if (D[i][k] + D[k][j] < D[i][j])
				{
					D[i][j] = D[i][k] + D[k][j];
					Path[i][j] = Path[k][j];
				}
			}
		}
	}
}
void DisplayPath(AMGraph G,int begin,int temp)
{
	if (Path[begin][temp] != -1)
	{
		DisplayPath(G, begin, Path[begin][temp]);
		printf("%c --> ", G.vexs[Path[begin][temp]]);
	}
}
int main()
{
	printf("************算法6.11 弗洛伊德算法**************\n\n");
	AMGraph G;
	int num_start, num_destination;
	char start, destination;
	CreateAMGraph(&G);

	//这个函数的作用就是把D[MVNum][MVNum] 和 Path[MVNum][MVNum] 这两个数组弄成最终版本
	//迪杰斯特拉算法是把放入一个源点,然后列出所有 源点 - n个顶点的  边表达式
	//弗洛伊德算法 不需要放入源点,只是得到 D[MVNum][MVNum] 和 Path[MVNum][MVNum]的两份表格
	//通过看表格D可以知道(vi,vj)之间的最短距离的权值
	//通过看表格Path可以知道(vi,vk,vj)之间的边关系(前驱索引)
	ShortestPath_Floyed(G);

	printf("请输入起点和终点(vi,vj):");
	scanf(" %c %c", &start, &destination);
	num_start = Locate(G, start);
	num_destination = Locate(G, destination);

	DisplayPath(G, num_start, num_destination);
	printf("%c\n", G.vexs[num_destination]);
	printf("最短路径为:%d\n", D[num_start][num_destination]);
}

 弗洛伊德算法有向图图片如下:

 弗洛伊德算法有向图终端输入如下:

************算法6.11 弗洛伊德算法**************

请输入顶点数+边数
4 8
请输入顶点信息
请输入第1个顶点:0
请输入第2个顶点:1
请输入第3个顶点:2
请输入第4个顶点:3

请输入边依附的顶点和权值
请输入第1条边依附的顶点和权值:0 1 1
请输入第2条边依附的顶点和权值:0 3 4
请输入第3条边依附的顶点和权值:1 2 9
请输入第4条边依附的顶点和权值:1 3 2
请输入第5条边依附的顶点和权值:3 2 6
请输入第6条边依附的顶点和权值:2 3 8
请输入第7条边依附的顶点和权值:2 1 5
请输入第8条边依附的顶点和权值:2 0 3
邻接矩阵有向网创建成功
请输入起点和终点(vi,vj):1 2
1 --> 3 --> 2
最短路径为:8

 

 

源点为 1 ,终点为2 ,那么<1,3><3,2>为最短路径,权值为8,读者想使用其他的起点终点可以复制代码运行去验证 

以下是有向图的D[w][w] 和Path[w][w]的信息:与上面的有向图对应的

标签:有向图,Path,printf,MVNum,C++,权值,顶点,数据结构,输入
From: https://blog.csdn.net/2305_78057683/article/details/143215922

相关文章

  • C++矩阵乘法
    题目描述计算两个矩阵的乘法。n×m 阶的矩阵 A 乘以m×k 阶的矩阵 B 得到的矩阵 C 是n×k 阶的,且 C[i][j]=A[i][0]×B[0][j]+A[i][1]×B[1][j]+C[i][j]=A[i][0]×B[0][j]+A[i][1]×B[1][j]+ …… +A[i][m−1]×B[m−1][j](C[i][j]+A[i][m−1]×B[m−1][j](C[i][......
  • C++入门基础
    少年不惧岁月长,彼方尚有荣光在。  前言 这是我自己学习C++的第一篇博客总结。后期我会继续把C++学习笔记开源至博客上。C++的兼容性1.C++兼容绝大多数C语言的语法,因此只需要把.c后缀文件改为.cpp即可。 VS编译器看到是.cpp就会调用C++编译器编译。#define......
  • 数据结构——队列和栈
    目录一、栈        1、概念与结构    2、栈的结构与初始化    3、入栈        4、出栈         5、取栈顶元素         6、取栈中有效元素个数          7、栈是否为空 二、队列     1、概念......
  • 数据结构 ——— C语言实现链式队列
    目录队列的概念以及示意图数组队列和链式队列链式队列的结构 实现链式队列的准备工作实现链式队列1.初始化2.打印队列的所有数据3.数据入队列(尾插)4.数据出队列(头删)5.访问队头的数据6.访问队尾的数据7.队列数据总个数8.判断队列是否为空9.释放队列的所......
  • 数据结构 ——— C语言实现数组栈
    目录栈的概念以及示意图链式栈和数组栈链式栈:数组栈:数组栈的结构实现数组栈的准备工作实现数组栈初始化数组栈入栈(尾插)出栈(尾删)访问栈顶数据判断栈是否为空栈数据的总数访问栈的所有数据释放栈Stack.h的所有代码Stack.c的所有代码栈的概念以及示意图栈......
  • Go语言和C++在内存管理上的比较
    #Go语言和C++在内存管理上的比较在探讨Go语言和C++在内存管理上的比较时,我们可以从几个核心观点进行分析:自动内存管理、性能、安全性。在这些核心方面,Go语言通过其垃圾回收机制提供了相对于C++更为自动化的内存管理方式,这一点在开发大型应用时尤为重要。自动内存管理是Go语言......
  • 数据结构有哪些
    数据结构分类涉及多方面,主要包括:1、线性结构、2、树形结构、3、图形结构、4、集合结构、5、文件结构。在这些种类中,线性结构是最基本、也是最为广泛使用的一种,它包括数组、链表、栈和队列等数据结构,通过线性的方式组织数据元素。以数组为例,它以连续的内存空间顺序存储数据,通过索引......
  • VS Code 配置 C/C++ 开发环境
     一、下载编译工具MinGWgithub上的版本更新较快github 配置系统环境,并验证 二、VSCode 1、VSCode 安装C/C++相关扩展2.VSCode添加编译器、并运行调试Ctrl+Shift+p 进入C/C++编辑配置,修改编译器目录 运行1.cpp 执行 ......
  • 【31】C++项目练习
    定义一个类Book,用来描述新书, 具有以下功能:查看当前价格.查看当前的书号定义一个类SellBook,用来表示促销的书籍, 要求继承自Book类具有以下功能:查看当前折扣设置当前折扣查看当前的促销价格下面是我自编的代码Book类 .h#pragmaonce#include<string>usi......
  • 基础数据结构(1)
    单链表与双链表的用处单链表单链表的存储:单链表的几种操作在表头插入一个数:先将这个数指向head指向的数,再将head指向这个数在表中的第k位后面插入一个数:先将这个数指向第k位指向的数,再将第k位指向这个数在表中删除一个数:让这个数直接指向下一个数的下一个数代码实现:/......