【数据结构】最短路径

在图论中,最短路径问题是一个经典且重要的问题,它用于寻找两个顶点之间距离最短的路径。本文将详细介绍两种常用的最短路径算法——Dijkstra算法和Bellman-Ford算法的原理,并提供C语言代码示例,演示它们的实现方式及应用场景。

一、Dijkstra算法

Dijkstra算法是一种贪心算法,用于求解带有非负权值的加权图的单源最短路径问题。它的基本思想是,从起始顶点开始,逐步扩展已经找到的最短路径集合,直到找到从起始顶点到所有其他顶点的最短路径。

理论知识:

  1. 初始化: 将起始顶点到所有其他顶点的距离初始化为无穷大,起始顶点到自身的距离初始化为0。
  2. 迭代过程: 每次从尚未访问的顶点中选择距离最短的顶点,更新与其相邻的顶点的距离。
  3. 终止条件: 所有顶点都被访问完毕,或者所有顶点都已经加入到最短路径集合中。

C语言实现:

下面是用C语言实现Dijkstra算法的示例代码:

#include <stdio.h>
#include <limits.h>

#define V 5 // 图中顶点数

int minDistance(int dist[], int sptSet[]) {
    int min = INT_MAX, min_index;
    for (int v = 0; v < V; v++) {
        if (sptSet[v] == 0 && dist[v] < min) {
            min = dist[v];
            min_index = v;
        }
    }
    return min_index;
}

void printSolution(int dist[]) {
    printf("顶点到源点的最短路径距离:\n");
    for (int i = 0; i < V; i++) {
        printf("%d -> %d\n", i, dist[i]);
    }
}

void dijkstra(int graph[V][V], int src) {
    int dist[V];
    int sptSet[V];

    for (int i = 0; i < V; i++) {
        dist[i] = INT_MAX;
        sptSet[i] = 0;
    }

    dist[src] = 0;

    for (int count = 0; count < V - 1; count++) {
        int u = minDistance(dist, sptSet);
        sptSet[u] = 1;

        for (int v = 0; v < V; v++) {
            if (!sptSet[v] && graph[u][v] && dist[u] != INT_MAX && dist[u] + graph[u][v] < dist[v]) {
                dist[v] = dist[u] + graph[u][v];
            }
        }
    }

    printSolution(dist);
}

int main() {
    int graph[V][V] = {
        {0, 4, 0, 0, 0},
        {4, 0, 8, 0, 0},
        {0, 8, 0, 7, 0},
        {0, 0, 7, 0, 9},
        {0, 0, 0, 9, 0}
    };

    dijkstra(graph, 0);

    return 0;
}

二、Bellman-Ford算法

Bellman-Ford算法是一种用于求解带有负权值的加权图的单源最短路径问题的动态规划算法。它的基本思想是,从源顶点开始,逐步扩展已经找到的最短路径集合,直到找到从源顶点到所有其他顶点的最短路径。

理论知识:

  1. 初始化: 将源顶点到所有其他顶点的距离初始化为无穷大,源顶点到自身的距离初始化为0。
  2. 迭代过程: 进行 V-1 次松弛操作,即尝试通过中间顶点更新顶点间的距离。

检测负权环: 再进行一次松弛操作,如果仍然可以更新距离,则图中存在负权环。

C语言实现:

下面是用C语言实现Bellman-Ford算法的示例代码:

#include <stdio.h>
#include <stdlib.h>
#include <limits.h>

#define V 5 // 图中顶点数
#define E 8 // 图中边数

typedef struct {
    int src, dest, weight;
} Edge;

void printSolution(int dist[]) {
    printf("顶点到源点的最短路径距离:\n");
    for (int i = 0; i < V; i++) {
        printf("%d -> %d\n", i, dist[i]);
    }
}

void bellmanFord(Edge edges[], int src) {
    int dist[V];

    for (int i = 0; i < V; i++) {
        dist[i] = INT_MAX;
    }

    dist[src] = 0;

    for (int i = 0; i < V - 1; i++) {
        for (int j = 0; j < E; j++) {
            int u = edges[j].src;
            int v = edges[j].dest;
            int weight = edges[j].weight;
            if (dist[u] != INT_MAX && dist[u] + weight < dist[v]) {
                dist[v] = dist[u] + weight;
            }
        }
    }

    for (int i = 0; i < E; i++) {
        int u = edges[i].src;
        int v = edges[i].dest;
        int weight = edges[i].weight;
        if (dist[u] != INT_MAX && dist[u] + weight < dist[v]) {
            printf("图中存在负权环\n");
            return;
        }
    }

    printSolution(dist);
}

int main() {
    Edge edges[E] = {
        {0, 1, -1}, {0, 2, 4}, {1, 2, 3}, {1, 3, 2},
        {1, 4, 2}, {3, 2, 5}, {3, 1, 1}, {4, 3, -3}
    };

    bellmanFord(edges, 0);

    return 0;
}

通过以上的理论介绍和C语言代码示例,我们深入了解了Dijkstra算法和Bellman-Ford算法这两种常用的最短路径算法,并学习了它们的实现方式及应用场景。在实际应用中,根据具体情况选择合适的算法,将有助于解决各种图相关的最短路径问题。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/578343.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Java学习路线及自我规划

荒废了一段时间&#xff0c;这段时间的总结开始了JavaWeb的学习但是困难重重&#xff0c;例如Maven&#xff0c;Vue的路由等&#xff0c;所以我反省了一段时间&#xff0c;因为基础薄弱&#xff0c;加之学习的资源是速成视频&#xff0c;导致大厦将倾的局面&#xff08;也算不上…

Golang | Leetcode Golang题解之第52题N皇后II

题目&#xff1a; 题解&#xff1a; func totalNQueens(n int) (ans int) {columns : make([]bool, n) // 列上是否有皇后diagonals1 : make([]bool, 2*n-1) // 左上到右下是否有皇后diagonals2 : make([]bool, 2*n-1) // 右上到左下是否有皇后var backtrack func(int)…

使用预训练模型构建自己的深度学习模型(迁移学习)

在深度学习的实际应用中&#xff0c;很少会去从头训练一个网络&#xff0c;尤其是当没有大量数据的时候。即便拥有大量数据&#xff0c;从头训练一个网络也很耗时&#xff0c;因为在大数据集上所构建的网络通常模型参数量很大&#xff0c;训练成本大。所以在构建深度学习应用时…

【redis】Redis数据类型(二)Hash类型

目录 Hash类型介绍特性hash 的内部编码方式/底层结构hashtableziplistlistpack 适用场景举例 常用命令hset示例 hsetnx示例&#xff1a; hmset示例 hget示例 hmget示例 hgetall示例 hdel示例 hlen示例 hexists示例 hincrby示例 hincrbyfloat示例 hkeys示例 hvals示例 Hash类型介…

VS2019编译OSG3.7.0+OSGEarth3.3+OSGQt5.15.2时遇到的问题及解决方法

注:本次编译以文章《VS2019编译OSG3.7.0+OSGEarth3.3+OSGQt》为基础搜集资料并进行编译 一 OSG编译 1.Osg3.7.0编译中,cmake阶段按照文章步骤即可。 2.另外,还需要对以下三项进行设置,参照《OSG-OpenSceneGraph在WIN10与VS2022下的部署(OSG3.6.5+VS2022+Win10_x64)个…

RustGUI学习(iced)之小部件(二):如何使用滑动条部件

前言 本专栏是学习Rust的GUI库iced的合集&#xff0c;将介绍iced涉及的各个小部件分别介绍&#xff0c;最后会汇总为一个总的程序。 iced是RustGUI中比较强大的一个&#xff0c;目前处于发展中&#xff08;即版本可能会改变&#xff09;&#xff0c;本专栏基于版本0.12.1. 概述…

mybatis基本使用

文章目录 1. mybatis2. 基本使用(1) maven坐标(2) 配置文件编写(3) 数据库操作(4) 注解查询 2. 基本配置(1) 读取外部配置文件(2) mapper映射 3. 映射文件查询删除/修改/新增 动态sql 1. mybatis MyBatis 是一款优秀的持久层框架&#xff0c;它支持自定义 SQL、存储过程以及高…

CSS盒子模型(如果想知道CSS有关盒子模型的知识点,那么只看这一篇就足够了!)

前言&#xff1a;在网页制作的时候&#xff0c;我们需要将网页中的元素放在指定的位置&#xff0c;那么我们如何将元素放到指定的位置上呢&#xff1f;这时候我们就需要了解盒子模型。 ✨✨✨这里是秋刀鱼不做梦的BLOG ✨✨✨想要了解更多内容可以访问我的主页秋刀鱼不做梦-CSD…

sCrypt全新上线RUNES功能

sCrypt智能合约平台全新上线一键etch/mint RUNES功能&#xff01; 请访问 https://runes.scrypt.io/ 或点击阅读原文体验&#xff01; 关于sCrypt sCrypt是BSV区块链上的一种智能合约高级语言。比特币使用基于堆栈的Script语言来支持智能合约&#xff0c;但是用原生Script编…

网络靶场实战-物联网安全Unicorn框架初探

背景 Unicorn 是一款基于 QEMU 的快速 CPU 模拟器框架&#xff0c;可以模拟多种体系结构的指令集&#xff0c;包括 ARM、MIPS、PowerPC、SPARC 和 x86 等。Unicorn使我们可以更好地关注 CPU 操作, 忽略机器设备的差异。它能够在虚拟内存中加载和运行二进制代码&#xff0c;并提…

密码加密案例

文章目录 描述思路错误关于增强for循环改变不了数组的值这一现象的疑问代码反思 描述 思路错误 应该是将其放入数组&#xff0c;而不是单纯的读到&#xff0c;因为你要对每一位数字进行操作 关于增强for循环改变不了数组的值这一现象的疑问 我们尝试使用增强for循环 键盘输…

uniapp使用地图开发app

使用uniapp开发app中使用到地图的坑&#xff1a; 1、简单使用地图的功能比较简单&#xff0c;仅使用到地图选点和定位功能&#xff1a;&#xff08;其中问题集中在uni.chooseLocation中&#xff09;下面是api官网地址 uni.getLocation(OBJECT) | uni-app官网 官方建议app端使…

迁移学习基础知识

简介 使用迁移学习的优势&#xff1a; 1、能够快速的训练出一个理想的结果 2、当数据集较小时也能训练出理想的效果。 注意&#xff1a;在使用别人预训练的参数模型时&#xff0c;要注意别人的预处理方式。 原理&#xff1a; 对于浅层的网络结构&#xff0c;他们学习到的…

视频批量剪辑新纪元:轻松调整音频采样率,一键实现高效视频处理!

视频剪辑已成为我们日常生活和工作中不可或缺的一部分。然而&#xff0c;面对大量的视频文件&#xff0c;如何高效地进行批量剪辑&#xff0c;同时又能轻松调整音频采样率&#xff0c;成为了许多视频制作人员、自媒体从业者、教育者和学生的共同需求。 第一步&#xff0c;进入…

[C++基础学习]----02-C++运算符详解

前言 C中的运算符用于执行各种数学或逻辑运算。下面是一些常见的C运算符及其详细说明&#xff1a;下面详细解释一些常见的C运算符类型&#xff0c;包括其原理和使用方法。 正文 01-运算符简介 算术运算符&#xff1a; a、加法运算符&#xff08;&#xff09;&#xff1a;对两个…

4.27日学习打卡----初学Redis(四)

4.27日学习打卡 目录&#xff1a; 4.27日学习打卡一. Redis的配置文件二. Redis构建Web应用实践环境搭建redis的优点引入本地缓存Google 开源工具GuavaGuava实现本地缓存 一. Redis的配置文件 在Redis的解压目录下有个很重要的配置文件 redis.conf &#xff0c;关于Redis的很多…

达梦(DM) SQL日期操作及分析函数

达梦DM SQL日期操作及分析函数 日期操作SYSDATEEXTRACT判断一年是否为闰年周的计算确定某月内第一个和最后一个周末某天的日期确定指定年份季度的开始日期和结束日期补充范围内丢失的值按照给定的时间单位查找使用日期的特殊部分比较记录 范围处理分析函数定位连续值的范围查找…

如何通过安全数据传输平台,保护核心数据的安全传输?

在数字化的浪潮中&#xff0c;企业的数据安全传输显得尤为关键。随着网络攻击手段的日益复杂&#xff0c;传统的数据传输方式已不再安全&#xff0c;这就需要我们重视并采取有效的措施&#xff0c;通过安全数据传输平台来保护核心数据。 传统的数据传输面临的主要问题包括&…

Bun 入门到精通(一)

Bun 是什么&#xff1f; Bun 是用于 JavaScript 和 TypeScript 应用程序的多合一工具包。它作为一个名为 bun 的可执行文件提供。 其核心是 Bun 运行时&#xff0c;这是一个快速的 JavaScript 运行时&#xff0c;旨在替代 Node.js。它是用 Zig 编写的&#xff0c;并由 JavaSc…

数字文旅重塑旅游发展新格局:以数字化转型为突破口,提升旅游服务的智能化水平,为游客带来全新的旅游体验

随着信息技术的迅猛发展&#xff0c;数字化已成为推动各行各业创新发展的重要力量。在旅游业领域&#xff0c;数字文旅的兴起正以其强大的驱动力&#xff0c;重塑旅游发展的新格局。数字文旅以数字化转型为突破口&#xff0c;通过提升旅游服务的智能化水平&#xff0c;为游客带…
最新文章