数据结构图之弗洛伊德算法


弗洛伊德算法

用于求取连通图中任意点到其他点的最短路径的算法,相比于迪杰斯特拉算法,在代码实现上更加简洁,复杂度系数也要小一些。

算法实现

#include<iostream>
using namespace std;
#define MAX 10000000
//打印路径经过的点
void PrintPath(int** path, int n, int i, int j);
//获取图矩阵
void GetArr(int**& arr, int n, int**& path);
//弗洛伊德算法
void Floyd(int** G, int** path, int n);
//int main()
//{
//	int** G = NULL, ** path = NULL;
//	int n;
//	cin >> n;
//	GetArr(G, n, path);
//	Floyd(G, path, n);
//	for(int i=0;i<n;i++)
//		for (int j = 0; j < n; j++)
//		{
//			cout << G[i][j] << ":";
//			if (i != j)
//			{
//				PrintPath(path, n, i, j);
//				cout << endl;
//			}
//			else
//				cout << i << endl;
//		}
//	/*
//	    4
//
//		9999     4    11    9999
//		  6    9999    2    9999
//		  1    9999   9999    1
//		9999     3    9999  9999
//		一组测试数据
//	*/
//	/*	
//		from 0 to 1: dist = 4 path : 0 1
//		from 0 to 2 : dist = 6 path : 0 1 2
//		from 0 to 3 : dist = 7 path : 0 1 2 3
//		from 1 to 0 : dist = 3 path : 1 2 0
//		from 1 to 1 : dist = 0 path : 1
//		from 1 to 2 : dist = 2 path : 1 2
//		from 1 to 3 : dist = 3 path : 1 2 3
//		from 2 to 0 : dist = 1 path : 2 0
//		from 2 to 1 : dist = 4 path : 2 3 1
//		from 2 to 2 : dist = 0 path : 2
//		from 2 to 3 : dist = 1 path : 2 3
//		from 3 to 0 : dist = 6 path : 3 1 2 0
//		from 3 to 1 : dist = 3 path : 3 1
//		from 3 to 2 : dist = 5 path : 3 1 2
//		from 3 to 3 : dist = 0 path : 3
//	*/
//	return 0;
//}

//获取图矩阵
void GetArr(int**& arr, int n,int**& path)
{
	arr = new int* [n];				//arr是图的邻接矩阵
	path = new int* [n];			//path是图的中间节点,path[i][j]的值代表i 到 j间的节点下标
	for (int i = 0; i < n; i++)		//如果是path[i][j]是-1则说明i 到 j间无中间路径
	{
		arr[i] = new int[n];
		path[i] = new int[n];
	}
	for (int i = 0; i < n; i++)
		for (int j = 0; j < n; j++)
		{
			cin >> arr[i][j];
			path[i][j] = -1;		//path初始所有都为-1
		}
}
//弗洛伊德算法
void Floyd(int** G, int** path, int n)
{
	for(int k=0;k<n;k++)						//k作为中间节点
		for(int i=0;i<n;i++)
			for (int j = 0; j < n; j++)
			{
				if (G[i][j] > G[i][k] + G[k][j])//如果节点i k j间有路径,且要小于i j间的路径则进行替换
				{
					G[i][j] = G[i][k] + G[k][j];
					path[i][j] = k;				//将i到j的中间路径存入k
				}
			}
}
//打印路径长经过的点
//使用递归实现
void PrintPath(int** path, int n, int i, int j)
{
	if (i == j)     //i=j说明是节点自己到自己,因此不做输出
	{
		return;
	}
	else if (path[i][j] == -1)		//到-1时表明前面的中间节点已经递归完毕,因此开始输出上一递归的中间节点
	{
		cout << i << " " << j << " ";
		return;
	}
	PrintPath(path, n, i, path[i][j]);//递归起始节点和接下来的中间节点
	cout << j << " ";				//打印终止节点
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值