迪杰斯特拉算法、弗洛伊德算法和BFS(广度优先搜索)

迪杰斯特拉算法、弗洛伊德算法和BFS(广度优先搜索)都是用于求解最短路径问题的经典算法,它们各自有不同的特点和适用场景。以下是对这三种算法的介绍、区别以及代码实现的简要概述。

迪杰斯特拉算法(Dijkstra's algorithm)

  1. 介绍

    • 迪杰斯特拉算法是一种单源最短路径算法,用于计算一个顶点到其他所有顶点的最短路径。
    • 该算法适用于有向图和带非负权值边的图。
    • 算法通过维护一个距离数组来记录每个顶点到起点的最短路径长度,并通过松弛操作不断更新最短路径。
  2. 特点

    • 简单易懂,可以得到正确的解。
    • 在稠密图中有较好的表现。
    • 无法处理带负权边的图和带有负循环的图。
// 省略了部分代码,包括结构体定义、数组初始化等
void ShortestPath_Dijkstra(MGraph G, int v0, PathMatrix *p, ShortPathTable *D) {
    int final[MAX_VERtEX_NUM]; // 用于存储各顶点是否已经确定最短路径的数组
    // 对各数组进行初始化
    for (int v = 0; v < G.vexnum; v++) {
        final[v] = 0;
        (*D)[v] = G.arcs[v0][v];
        (*p)[v] = 0;
    }
    // 源点到自身的距离为0
    (*D)[v0] = 0;
    final[v0] = 1;
    int k = 0;
    for (int i = 0; i < G.vexnum; i++) {
        int min = INFINITY;
        // 选择到各顶点权值最小的顶点
        for (int w = 0; w < G.vexnum; w++) {
            if (!final[w] && (*D)[w] < min) {
                k = w;
                min = (*D)[w];
            }
        }
        // 设置该顶点的标志位为1
        final[k] = 1;
        // 更新源点到各顶点的权值
        for (int w = 0; w < G.vexnum; w++) {
            if (!final[w] && (min + G.arcs[k][w] < (*D)[w])) {
                (*D)[w] = min + G.arcs[k][w];
                (*p)[w] = k; // 记录路径
            }
        }
    }
}

弗洛伊德算法(Floyd-Warshall algorithm)

  1. 介绍

    • 弗洛伊德算法是一种多源最短路径算法,用于计算任意两个顶点之间的最短路径。
    • 该算法适用于带有任意权值边的图。
    • 算法通过维护一个邻接矩阵来记录每对顶点之间的最短路径长度,并通过动态规划的方法不断更新最短路径。
  2. 特点

    • 可以处理带负权边的图和带有负循环的图。
    • 能够找到所有最短路径。
    • 时间复杂度较高,不适用于大规模图的计算。
  3. 代码实现(C语言示例,简化版):

// 省略了部分代码,包括结构体定义、数组初始化等
void Floyd(MGraph G, PathMatrix *path, ShortPathTable *D) {
    int n = G.vexnum;
    // 初始化距离矩阵和路径矩阵
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            (*D)[i][j] = G.arcs[i][j];
            (*path)[i][j] = j;
        }
    }
    // 动态规划求解最短路径
    for (int k = 0; k < n; k++) {
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < n; j++) {
                if ((*D)[i][k] + (*D)[k][j] < (*D)[i][j]) {
                    (*D)[i][j] = (*D)[i][k] + (*D)[k][j];
                    (*path)[i][j] = k; // 更新路径
                }
            }
        }
    }
}

BFS(广度优先搜索)

  1. 介绍

    • BFS是一种图搜索算法,可以用于求解无权图或所有边的权值都相同的图中的最短路径问题。
    • 算法通过逐层扩展节点来搜索图中的路径。
  2. 特点

    • 适用于无权图或所有边的权值都相同的图。
    • 通过队列实现节点的逐层扩展。
    • 在无权图中,BFS可以找到从起点到终点的最短路径(边数最少)。
  3. 代码实现(JavaScript示例):

function BFS_MIN_Distance(G, u) {
    let d = new Array(G.vexnum).fill(-1); // 初始化路径长度
    let path = new Array(G.vexnum).fill(-1); // 最短路径从哪个顶点过来
    let visited = new Array(G.vexnum).fill(false); // 访问标记
    let Q = []; // 队列

    d[u] = 0;
    visited[u] = true;
    Q.push(u);

    while (Q.length > 0) {
        let current = Q.shift();
        for (let w = G.FirstNeighbor(current); w >= 0; w = G.NextNeighbor(current, w)) {
            if (!visited[w]) {
                d[w] = d[current] + 1;
                path[w] = current;
                visited[w] = true;
                Q.push(w);
            }
        }
    }

    return { d, path };
}

区别

  1. 适用范围

    • 迪杰斯特拉算法适用于有向图和带非负权值边的图。
    • 弗洛伊德算法适用于带有任意权值边的图。
    • BFS适用于无权图或所有边的权值都相同的图。
  2. 算法类型

    • 迪杰斯特拉算法是单源最短路径算法。
    • 弗洛伊德算法是多源最短路径算法。
    • BFS是一种图搜索算法,但在无权图中可用于求解最短路径。
  3. 时间复杂度

    • 迪杰斯特拉算法的时间复杂度为O(V^2),其中V是顶点数。
    • 弗洛伊德算法的时间复杂度为O(V^3)。
    • BFS的时间复杂度取决于图的边数和节点的扩展速度,通常与图的规模和结构有关。O(V^2)或者O(V+E)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值