C# 弗洛伊德(Floyd)算法

弗洛伊德(Floyd)算法 主要是用于计算图中所有顶点对之间的最短距离长度的算法,如果是要求某一个特定点到图中所有顶点之间的最短距离可以用Dijkstra(迪杰斯特拉)算法来求。

弗洛伊德(Floyd)算法的算法过程是:

1、从任意一条单边路径开始。所有两点之间的距离是边的权,如果两点之间没有边相连,则权为无穷大。

2、对于每一对顶点 u 和 v,看看是否存在一个顶点 w 使得从 u 到 w 再到 v 比已知的路径更短。如果是更新它。

把图用邻接矩阵G表示出来,如果从Vi到Vj有路可达,则G[i,j]=d,d表示该路的长度;否则G[i,j]=无穷大。定义一个矩阵D用来记录所插入点的信息,D[i,j]表示从Vi到Vj需要经过的点,初始化D[i,j]=j。把各个顶点插入图中,比较插点后的距离与原来的距离,G[i,j] = min( G[i,j], G[i,k]+G[k,j] ),如果G[i,j]的值变小,则D[i,j]=k。在G中包含有两点之间最短道路的信息,而在D中则包含了最短路径的信息。

比如,要寻找从V5到V1的路径。根据D,假如D(5,1)=3则说明从V5到V1经过V3,路径为{V5,V3,V1},如果D(5,3)=3,说明V5与V3直接相连,如果D(3,1)=1,说明V3与V1直接相连。

时间复杂度和空间复杂度

时间复杂度:O(n^3);

空间复杂度: O(n^2);

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConAppFlody
{
   
    class Program
    {
        private const int MaxSize = 6;
        private const int INF = 32767;    //INF表示∞
        private const int MAXV = 4;    //最大顶点个数
        //结构体的成员定义里不能直接赋值,也就是等号后的应该移除,在你后面实例化整个结构体以后,
        //再对Study_Data[n].input=new double[50] 其他成员类似。顺便说下其实用class简单得多。

struct VertexType
        {
            public int no;                        //顶点编号
            public int info;                    //顶点其他信息
        } ;                               //顶点类型
        struct MGraph                    //图的定义
        {
            public int[,] edges;       //邻接矩阵
            public int n, e;             //顶点数,弧数
            public VertexType[] vexs;          //存放顶点信息
        } ;                               //图的邻接矩阵类型

static void initdata()
        {
            int i,j;
            MGraph g;
            g.n = MAXV; g.e = 8;
            g.edges = new int[MAXV, MAXV];
            g.vexs = new VertexType[MAXV];
            //int [,] anArray = new int [2, 4] {{1,2,3,4},{5,6,7,8}};
            int[,] a = new int[MAXV, MAXV] {
            {0, 5,INF,7},
            {5, 0,  4,1},
            {INF, 4, 0,INF},
            {7,1,INF,0}
            };

for (i = 0; i < g.n; i++)        //建立图的图的邻接矩阵
                for (j = 0; j < g.n; j++)
                    g.edges[i, j] = a[i, j];///////////////////////////////////////////////
            Console.WriteLine("各顶点的最短路径:");
            Floyd(g);
          
    
        }

static void Floyd(MGraph g)
        {
            int[,] A = new int[MAXV, MAXV];//A用于存放当前顶点之间的最短路径长度,分量A[i][j]表示当前顶点vi到顶点vj的最短路径长度。
            int[,] path = new int[MAXV, MAXV];//从顶点vi到顶点vj的路径上所经过的顶点编号不大于k的最短路径长度。
            int i, j, k;
            for (i = 0; i < g.n; i++)
            {
                for (j = 0; j < g.n; j++)//对各个节点初始已经知道的路径和距离
                {
                    A[i, j] = g.edges[i, j];
                    path[i, j] = -1;
                }
            }
            for (k = 0; k < g.n; k++)
            {
                for (i = 0; i < g.n; i++)
                    for (j = 0; j < g.n; j++)
                        if (A[i, j] > A[i, k] + A[k, j])//从i到j的路径比从i经过k到j的路径长
                        {
                            A[i, j] = A[i, k] + A[k, j];//更改路径长度
                            path[i, j] = k;//更改路径信息经过k
                        }
            }

Dispath(A, path, g.n);   //输出最短路径
        }

static void Dispath(int[,] A, int[,] path, int n)
        {

int i, j;
            for (i = 0; i < n; i++)
                for (j = 0; j < n; j++)
                {
                    if (A[i, j] == INF)
                    {
                        if (i != j)
                        {

Console.WriteLine("从{0}到{1}没有路径\n", i, j);
                        }
                       
                    }
                    else
                    {
                        Console.Write("从{0}到{1}=>路径长度:{2} 路径:", i, j, A[i, j]);
                        
                        Console.Write("{0},", i);    //输出路径上的起点
                        Ppath(path,i,j);            //输出路径上的中间点
                        Console.WriteLine("{0}", j);    //输出路径上的终点
                    }
                }
        }

static void Ppath(int[,] path, int i, int j)  //前向递归查找路径上的顶点
        {
            int k;
            k = path[i, j];
            if (k == -1) return;    //找到了起点则返回
            Ppath(path, i, k);    //找顶点i的前一个顶点k

Console.Write("{0},", k);    //输出路径上的终点
            Ppath(path, k, j);    //找顶点k的前一个顶点j
        }

static void Main(string[] args)
        {
            initdata();
            
            //Console.Write("{0}", MaxSize);
            //Console.Write("{0}", MAXV);
            Console.ReadKey();
        }
    }
}

时间: 2024-10-09 02:26:50

C# 弗洛伊德(Floyd)算法的相关文章

44. 蛤蟆的数据结构笔记之四十四弗洛伊德Floyd算法

44. 蛤蟆的数据结构笔记之四十四弗洛伊德Floyd算法 本篇名言:"希望是厄运的忠实的姐妹. --普希金" 我们继续来看下数据结构图中的一个算法,这个算法来自图灵奖得主. 1.  Floyd算法介绍 Floyd算法又称为插点法,是一种用于寻找给定的加权图中多源点之间最短路径的算法.该算法名称以创始人之一.1978年图灵奖获得者.斯坦福大学计算机科学系教授罗伯特·弗洛伊德命名.注意这个可不是心理学的那个弗洛伊德. 是解决任意两点间的最短路径的一种算法,可以正确处理有向图或负权的最短路径

[Python] 弗洛伊德(Floyd)算法求图的直径并记录路径

相关概念 对于一个图G=(V, E),求图中两点u, v间最短路径长度,称为图的最短路径问题.最短路径中最长的称为图的直径. 其中,求图中确定的某两点的最短路径算法,称为单源最短路径算法.求图中任意两点间的最短路径算法,称为多源最短路径算法. 常用的路径算法有: Dijkstra算法 SPFA算法\Bellman-Ford算法 Floyd算法\Floyd-Warshall算法 Johnson算法 其中最经典的是Dijkstra算法和Floyd算法.Floyd算法是多源最短路径算法,可以直接求出图

JS实现最短路径之弗洛伊德(Floyd)算法

弗洛伊德算法是实现最小生成树的一个很精妙的算法,也是求所有顶点至所有顶点的最短路径问题的不二之选.时间复杂度为O(n3),n为顶点数. 精妙之处在于:一个二重初始化,加一个三重循环权值修正,完成了所有顶点至所有顶点的的最短路径计算,代码及其简洁 JS实现: //定义邻接矩阵 let Arr2 = [ [0, 1, 5, 65535, 65535, 65535, 65535, 65535, 65535], [1, 0, 3, 7, 5, 65535, 65535, 65535, 65535], [

弗洛伊德(Floyd)算法

1 #include <stdio.h> 2 3 #define MAXVEX 20 //最大顶点数 4 #define INFINITY 65535 //∞ 5 6 7 typedef struct 8 {/* 图结构 */ 9 int vexs[MAXVEX];//顶点下标 10 int arc[MAXVEX][MAXVEX];//矩阵 11 int numVertexes, numEdges;//顶点数和边数 12 }MGraph; 13 14 //用户定义类型 15 typedef i

多源最短路Floyd 算法————matlab实现

弗洛伊德(Floyd)算法是一种用于寻找给定的加权图中顶点间最短路径的算法.该算法名称以创始人之一.1978年图灵奖获得者.斯坦福大学计算机科学系教授罗伯特·弗洛伊德命名. 基本思想 通过Floyd计算图G=(V,E)中各个顶点的最短路径时,需要引入一个矩阵S,矩阵S中的元素a[i][j]表示顶点i(第i个顶点)到顶点j(第j个顶点)的距离. 假设图G中顶点个数为N,则需要对矩阵S进行N次更新.初始时,矩阵S中顶点a[i][j]的距离为顶点i到顶点j的权值:如果i和j不相邻,则a[i][j]=∞

Floyd算法(三)之 Java详解

前面分别通过C和C++实现了弗洛伊德算法,本文介绍弗洛伊德算法的Java实现. 目录 1. 弗洛伊德算法介绍 2. 弗洛伊德算法图解 3. 弗洛伊德算法的代码说明 4. 弗洛伊德算法的源码 转载请注明出处:http://www.cnblogs.com/skywang12345/ 更多内容:数据结构与算法系列 目录 弗洛伊德算法介绍 和Dijkstra算法一样,弗洛伊德(Floyd)算法也是一种用于寻找给定的加权图中顶点间最短路径的算法.该算法名称以创始人之一.1978年图灵奖获得者.斯坦福大学计

Floyd算法(二)之 C++详解

本章是弗洛伊德算法的C++实现. 目录 1. 弗洛伊德算法介绍 2. 弗洛伊德算法图解 3. 弗洛伊德算法的代码说明 4. 弗洛伊德算法的源码 转载请注明出处:http://www.cnblogs.com/skywang12345/ 更多内容:数据结构与算法系列 目录 弗洛伊德算法介绍 和Dijkstra算法一样,弗洛伊德(Floyd)算法也是一种用于寻找给定的加权图中顶点间最短路径的算法.该算法名称以创始人之一.1978年图灵奖获得者.斯坦福大学计算机科学系教授罗伯特·弗洛伊德命名. 基本思想

Floyd算法之java详解

弗洛伊德算法介绍 和Dijkstra算法一样,弗洛伊德(Floyd)算法也是一种用于寻找给定的加权图中顶点间最短路径的算法.该算法名称以创始人之一.1978年图灵奖获得者.斯坦福大学计算机科学系教授罗伯特·弗洛伊德命名. 基本思想 通过Floyd计算图G=(V,E)中各个顶点的最短路径时,需要引入一个矩阵S,矩阵S中的元素a[i][j]表示顶点i(第i个顶点)到顶点j(第j个顶点)的距离. 假设图G中顶点个数为N,则需要对矩阵S进行N次更新.初始时,矩阵S中顶点a[i][j]的距离为顶点i到顶点

Floyd算法(一)之 C语言详解

本章介绍弗洛伊德算法.和以往一样,本文会先对弗洛伊德算法的理论论知识进行介绍,然后给出C语言的实现.后续再分别给出C++和Java版本的实现. 目录 1. 弗洛伊德算法介绍 2. 弗洛伊德算法图解 3. 弗洛伊德算法的代码说明 4. 弗洛伊德算法的源码 转载请注明出处:http://www.cnblogs.com/skywang12345/ 更多内容:数据结构与算法系列 目录 弗洛伊德算法介绍 和Dijkstra算法一样,弗洛伊德(Floyd)算法也是一种用于寻找给定的加权图中顶点间最短路径的算