数据结构——图——最短路径D&F算法

一、Dijkstra算法(贪心地求最短距离的算法)

  在此算法中,我按照自己的理解去命名,理解起来会轻松一些。

  

#define MAXSIZE 100
#define UNVISITED 0
#define VISITED 1
#define INFINITY 66666

typedef struct tool {
    int visited[MAXSIZE];
    /*是否已访问的数组,visited[i]表示顶点i已经访问,也就是到顶点i的最短距离已求出*/
    int known_shortest_distance[MAXSIZE];
    /*已知的最短距离数组。known_shortest_distance[i]代表从V0到Vi的最短距离*/
    int previous_vertex[MAXSIZE];
    /*previous_vertex[i]=j,代表:在从V0到Vi的最短路径上,顶点i的前一个顶点是顶点j*/
} Tool;

typedef struct gragh {
    int num_of_vertexes;
    int adjacent_matrix[MAXSIZE][MAXSIZE];
} Gragh;

void init_tool(Gragh g, Tool &t) {
    int i = 0;
    for(i = 0; i < g.num_of_vertexes; i++) {
        t.visited[i] = UNVISITED;
        t.known_shortest_distance[i] = g.adjacent_matrix[0][i];
        t.previous_vertex[i] = 0;
    }
}

void dijstra_shortest_distance(Gragh g, Tool &t) {
    int i, j, x; //循环变量
    int min_distance, x_index;
    /*min_distance存储的是当前已知的最短距离数组中从V0到Vx最小的距离;
    x_index存储的Vx的下标*/
    init_tool(g, t);
    for(i = 0; i < g.num_of_vertexes; i++) {
        min_distance = INFINITY;
        for(x = 0; x < g.num_of_vertexes; x++) {
            if(!t.visited[x] && t.known_shortest_distance[x] < min_distance) {
                min_distance = t.known_shortest_distance[x];
                x_index = x;
            }
        }
        /*通过上面一个循环,最短距离数组中的最小值就是min_distance;
        该顶点的下标就是x_index;
        在当前没有访问且以V0为起点距离最短的顶点中,
        这个点的下标就是x_index.*/
        t.visited[x_index] = VISITED;

        for(j = 0; j < g.num_of_vertexes; j++) {
            if(!t.visited[j] && (min_distance + g.adjacent_matrix[x_index][j] < t.known_shortest_distance[j])) {
                t.known_shortest_distance[j] = min_distance + g.adjacent_matrix[x_index][j];
                t.previous_vertex[j] = x_index;
            }
        }
    }

}

一、Floyd算法(不管三七二十一,先把整个图中任意两点的最短距离求出再说)

typedef struct floyd_tool {
    int known_shortest_distance[MAXSIZE][MAXSIZE];
    /*已知的最短距离数组。known_shortest_distance[i][j]代表从Vi到Vj的最短距离*/
    int path_matrix[MAXSIZE][MAXSIZE];
    /*path_matrix[i][j]=k,代表:在从Vi到Vj的最短路径上,要经过顶点k;
    用k代替i,直到path_matrix[k][j]=j*/
} FloydTool;

void init_floyd_tool(FloydTool &ft, Gragh g) {
    for(int i = 0; i < g.num_of_vertexes; i++) {
        for(int j = 0; j < g.num_of_vertexes; j++) {
            ft.known_shortest_distance[i][j] = g.adjacent_matrix[i][j];
            ft.path_matrix[i][j] = j;
        }
    }
}

void floyd_shortest_distance(Gragh g,FloydTool &ft) {
    init_floyd_tool(ft,g);
    for(int i = 0;i < g.num_of_vertexes; i++){
        for(int j = 0;j < g.num_of_vertexes;j++){
            for(int k = 0;k < g.num_of_vertexes;k++){
                if(ft.known_shortest_distance[j][k] >
                   ft.known_shortest_distance[j][i] + ft.known_shortest_distance[i][k]){
                    ft.known_shortest_distance[j][k] =
                    ft.known_shortest_distance[j][i] + ft.known_shortest_distance[i][k];
                    ft.path_matrix[j][k] = ft.path_matrix[j][i];
                   }
            }
        }
    }
}

改进版:

void floyd_shortest_distance(Gragh g,FloydTool &ft) {
    init_floyd_tool(ft,g);
    for(int i = 0;i < g.num_of_vertexes; i++){
        for(int j = 0;j < g.num_of_vertexes;j++){
            if(ft.known_shortest_distance[j][i] == INFINITY)continue;
            for(int k = j + 1;k < g.num_of_vertexes;k++){
                if(ft.known_shortest_distance[k][i] == INFINITY)continue;
                if(ft.known_shortest_distance[j][k] >
                   ft.known_shortest_distance[j][i] + ft.known_shortest_distance[i][k]){
                    ft.known_shortest_distance[j][k] =
                    ft.known_shortest_distance[j][i] + ft.known_shortest_distance[i][k];
                    ft.path_matrix[j][k] = ft.path_matrix[j][i];
                   }
            }
        }
    }
}
时间: 2024-10-20 14:10:53

数据结构——图——最短路径D&F算法的相关文章

数据结构--图--最小生成树(Prim算法)

构造连通网的最小生成树,就是使生成树的边的权值之和最小化.常用的有Prim和Kruskal算法.先看Prim算法:假设N={V,{E}}是连通网,TE是N上最小生成树中边的集合.算法从U={u0}(uo属于V),TE={}开始,重复执行下述操作:在所有u属于U,v属于V-U的边(u,v)属于E中找到代价最小的一条边(u0,v0)并入集合TE,同时v0并入U,直至U=V为止.此时TE中必有n-1条边,T={V,{TE}}为N的最小生成树.为实现此算法,需另设一个辅助数组closedge,以记录从U

数据结构(五)图---最短路径(弗洛伊德算法)

一:定义 弗洛伊德算法是用来求所有顶点到所有顶点的时间复杂度. 虽然我们可以直接对每个顶点通过迪杰斯特拉算法求得所有的顶点到所有顶点的时间复杂度,时间复杂度为O(n*3),但是弗洛伊德算法更加简洁优雅 二:弗洛伊德的使用介绍 若是求一个顶点到其他顶点的最短距离,例如迪杰斯特拉算法,我们的距离数组和路径数组使用一维即可,但是我们这里是获取所有顶点到其余顶点的最短距离,所以我们对于数组和路径都需要使用二维数组来表示 下面我们使用一个有三个顶点的图来进行讲解: (1)我们先定义两个二维数组D0[3][

实用数据结构---图的操作和算法

图算法的源代码.包含大量的注释,和最小生成树.最短路径.邻接表图深度广度优先搜索,邻接矩阵图深度广度优先搜索,欢迎借鉴 #include<stdio.h> #include<stdlib.h> #define MAXVEX 20 #define INFINITY 65535 typedef char vertexType; typedef int edgeType; typedef int Boolean; typedef int Pathmatirx[MAXVEX]; //用于存

图的单源最短路径:Dijkstra算法实现

本文介绍的是图的非负权值的单源最短路径问题.问题的提出是,对于有权图D,t提供源点v,要找到从v到其他所有点的最短路径,即单源最短路径问题,在本文中,解决这一问题,是普遍比较熟悉的Dijkstra算法. 算法核心思想参见维基.简而言之,设集合S存放已经求出了最短路径的点.初始状态S中只有一个点v0,之后每求得v0到vn的最短路径,就会更新v0到所有vn邻接的点的一致的最短路径(不一定是最终的最短路径),如此重复,每次会确定v0到一个点的最短路径,确定好的点加入S中,直至所有点进入S结束.在本文中

数据结构--图(中)--最短路径问题

最短路径问题 最短路径: 边上的权重就是距离. 最便宜: 权重是价格. 最快的路径: 通过结点最少 最短路径问题的抽象 在网络中,求两个不通顶点之间的所有路径中,边的权值之和最小的那一条路径 这条路径就是两点之间的最短路径 第一个顶点为源点 最后一个顶点为终点 问题分类 单源最短路径问题:从某固定源点出发,求其到所有其他顶点的最短路径. (有向)无权图 (有向)有权图 多源最短路径问题:求任意两顶点间的最短路径. 单源最短路径在每个节点上用一遍就是多源最短路径. 单源无权图 最短路径问题 思路是

JavaScript数据结构——图的实现

在计算机科学中,图是一种网络结构的抽象模型,它是一组由边连接的顶点组成.一个图G = (V, E)由以下元素组成: V:一组顶点 E:一组边,连接V中的顶点 下图表示了一个图的结构: 在介绍如何用JavaScript实现图之前,我们先介绍一些和图相关的术语. 如上图所示,由一条边连接在一起的顶点称为相邻顶点,A和B是相邻顶点,A和D是相邻顶点,A和C是相邻顶点......A和E是不相邻顶点.一个顶点的度是其相邻顶点的数量,A和其它三个顶点相连,所以A的度为3,E和其它两个顶点相连,所以E的度为2

?数据结构-图之强连通

数据结构-图之强连通 在一个无向图G中,若从顶点v_i到顶点v_j有路径相连(当然从v_j到v_i也一定有路径),则称v_i和v_j是连通的.如果G是有向图,那么连接v_i和v_j的路径中所有的边都必须同向.如果图中任意两点都是连通的,那么图被称作连通图.图的连通性是图的基本性质. 连通分量:无向图G的一个极大连通子图称为G的一个连通分量(或连通分支).连通图只有一个连通分量,即其自身:非连通的无向图有多个连通分量. 初级通路:通路中所有的顶点互不相同.初级通路必为简单通路,但反之不真. 强连通

算法导论——最短路径:BellmanFord算法

package org.loda.graph; import org.loda.structure.Stack; import org.loda.util.In; /** * * @ClassName: BellmanFord * @Description: 最短路径问题 * * 通用最短路径算法,能解决除了含负权重环以外的所有情况的最短路径,包括了含有负权重边的有向加权图 * * @author minjun * @date 2015年5月28日 下午11:04:45 * */ public

数据结构--图 的JAVA实现(上)

1,摘要: 本系列文章主要学习如何使用JAVA语言以邻接表的方式实现了数据结构---图(Graph),这是第一篇文章,学习如何用JAVA来表示图的顶点.从数据的表示方法来说,有二种表示图的方式:一种是邻接矩阵,其实是一个二维数组:一种是邻接表,其实是一个顶点表,每个顶点又拥有一个边列表.下图是图的邻接表表示. 从图中可以看出,图的实现需要能够表示顶点表,能够表示边表.邻接表指是的哪部分呢?每个顶点都有一个邻接表,一个指定顶点的邻接表中,起始顶点表示边的起点,其他顶点表示边的终点.这样,就可以用邻