最短路径——dijkstra算法代码(c语言)
最短路径问题
看了王道的视频,感觉云里雾里的,所以写这个博客来加深理解。(希望能在12点以前写完)
一、总体思想
dijkstra算法的主要思想就是基于贪心,找出从v开始的顶点到各个点的最短路径,做法入下
1.初始化三个辅助数组
s[],dist[],path[]
s[]:这个数组用来标记结点的访问与否,如果该结点被访问,则为1,如果该结点还没有访问,则为0;
dist[]:这个数组用来记录当前从v到各个顶点的最短路径长度,算法的核心思想就是通过不断修改这个表实现;
path[]:这个数组用来存放最短路径;
2.遍历图,修改上面的各项数组,每次只找最短路径,直到遍历结束
二、代码实现
void dijkstra(Graph G, int v)
{
int s[G.vexnum];
int dist[G.vexnum];
int path[G.vexnum];
for(int i = ; i < G.vexnum; i++)
{
s[i] = ;
dist[i] = G.edge[v][i];
if(G.edge[v][i] == max || G.edge[v][i] == )
{
path[i] = -;
}
else
{
path[i] = v;
}
s[v] = ;
} for(int i = ; i < G.vexnum; i++)
{
int min = max;
int u;
for(int j = ; j < G.vexnum; j++)
{
if(s[j] != && dist[j] < min)
{
min = dist[j];
u = j;
}
}
s[u] = ;
for(int j = ; j < G.vexnum; j++)
{
if(s[j] != && dist[j] > dist[u] + G.edge[u][j])
{
dist[j] = dist[u] + G.edge[u][j];
path[j] = u;
}
}
}
}
三、代码解释
先自己定义一个无穷大的值max
#define max inf
dijkstra算法传入的两个参为
图Graph G;
起点结点 int v;
首先我们需要三个辅助数组
int s[G.vexnum];//记录结点时是否被访问过,访问过为1, 没有访问过为0
int dist[G.vexnum];//记录当前的从v结点开始到各个结点的最短路径长度
int path[G.vexnum];//记录最短路径,存放的是该结点的上一个为最短路径的前驱结点
初始化三个数组
for(int i = ; i < G.vexnum; i++)
{
s[i] = ;//目前每个结点均未被访问过,设为0
dist[i] = G.edge[v][i];//dist[]数组记录每个从v结点开到其他i结点边的长度(权值)
if(G.edge[v][i] == max || G.edge[v][i] == )
{
path[i] = -;
}//如果v到i不存在路径或者i就是v结点时,将path[i]设为-1,意为目前v结点不存在路径到i
else
{
path[i] = v;
}//反之,若v到i存在路径,则v就是i的前驱结点,将path[i] = v
s[v] = ;//从遍历起点v开始,即已经访问过顶点s[v]=1
}
开始遍历数组并且每次修改辅助数组以记录目前的情况,直至遍历结束
for(int i = ; i < G.vexnum; i++)
{
int min = max;//声明一个min = max用来每次记录这次遍历找到的最短路径的长度(权值)
int u;//声明u来记录这次历找到的最短路径的结点
for(int j = ; j < G.vexnum; j++)//开始遍历 找目前的最短路径
{
if(s[j] != && dist[j] < min)
{
min = dist[j];
u = j;
}//找出v到结点j的最短路径,并且记录下最短路径的结点u = j
}
s[u] = ;//找到结点u,即已访问过u,s[u] = 1
for(int j = ; j < G.vexnum; j++)//开始遍历 修改辅助数组的值
{
if(s[j] != && dist[j] > dist[u] + G.edge[u][j])
{
dist[j] = dist[u] + G.edge[u][j];
path[j] = u;
}//如果v→j的路径比v →u→j长,那么修改dist[j]的值为 dist[u] + G.edge[u][j],并且修改j的前驱结点为path[j] = u
}
}
遍历结束后,数组dist[]就是存放了起点v开始到各个顶点的最短路径长度
最短路径包含的结点就在path数组中
例如我们得到如下的path[]数组
path[] = -;//0到自己无前驱结点
path[] = ;//1的前驱为结点0,0无前驱结点,即最短路径为0 →1
path[] = ;//2的前驱结为点1,1的前驱结点0,0无前驱结点,即最短路径为0 →1 →2
path[] = ;//3的前驱为结点0,0无前驱结点,即最短路径为0 →3
path[] = ;//4的前驱结为点2,2的前驱结为点1,1的前驱结点0,0无前驱结点,即最短路径为0 →1 →2 →4
其实不难看出,每次都会标记已经访问过的节点,访问过的节点不会再更改,即 这样的算法不可逆,也就是dijkstra对于存在负权值的图不适用,明天再更新Floyd算法叭
最短路径——dijkstra算法代码(c语言)的更多相关文章
- 最短路径-Dijkstra算法与Floyd算法
一.最短路径 ①在非网图中,最短路径是指两顶点之间经历的边数最少的路径. AE:1 ADE:2 ADCE:3 ABCE:3 ②在网图中,最短路径是指两顶点之间经历的边上权值之和最短的路径 ...
- 最短路径——Dijkstra算法以及二叉堆优化(含证明)
一般最短路径算法习惯性的分为两种:单源最短路径算法和全顶点之间最短路径.前者是计算出从一个点出发,到达所有其余可到达顶点的距离.后者是计算出图中所有点之间的路径距离. 单源最短路径 Dijkstra算 ...
- 网络最短路径Dijkstra算法
最近在学习算法,看到有人写过的这样一个算法,我决定摘抄过来作为我的学习笔记: <span style="font-size:18px;">/* * File: shor ...
- 带你找到五一最省的旅游路线【dijkstra算法代码实现】
算法推导过程参见[dijkstra算法推导详解] 此文为[dijkstra算法代码实现] https://www.cnblogs.com/Halburt/p/10767389.html package ...
- 单源最短路径Dijkstra算法,多源最短路径Floyd算法
1.单源最短路径 (1)无权图的单源最短路径 /*无权单源最短路径*/ void UnWeighted(LGraph Graph, Vertex S) { std::queue<Vertex&g ...
- 数据结构实验之图论七:驴友计划 ( 最短路径 Dijkstra 算法 )
数据结构实验之图论七:驴友计划 Time Limit: 1000 ms Memory Limit: 65536 KiB Submit Statistic Discuss Probl ...
- 有向网络(带权的有向图)的最短路径Dijkstra算法
什么是最短路径? 单源最短路径(所谓单源最短路径就是只指定一个顶点,最短路径是指其他顶点和这个顶点之间的路径的权值的最小值) 什么是最短路径问题? 给定一带权图,图中每条边的权值是非负的,代表着两顶点 ...
- Python数据结构与算法之图的最短路径(Dijkstra算法)完整实例
本文实例讲述了Python数据结构与算法之图的最短路径(Dijkstra算法).分享给大家供大家参考,具体如下: # coding:utf-8 # Dijkstra算法--通过边实现松弛 # 指定一个 ...
- 单源最短路径 dijkstra算法实现
本文记录一下dijkstra算法的实现,图用邻接矩阵表示,假设图为无向图.而且连通,有向图,不连通图的做法相似. 算法简述: 首先确定"单源"的源.假设是第0个顶点. 维护三个数组 ...
随机推荐
- pytorch中CUDA类型的转换
import torch import numpy as np device = torch.device("cuda:0" if torch.cuda.is_available( ...
- 深入研究Clang(十) Clang Static Analyzer简介
Clang Static Analyzer 官网地址:http://clang-analyzer.llvm.org/ Clang Static Analyer是一个源码分析工具,它可以发现C.C++和 ...
- $_server[]关于浏览器和服务器的参数获取
$_SERVER['USER'] www $_SERVER['HOME'] /home/www $_SERVER['HTTP_UPGRADE_INSECURE_REQUESTS'] 1 $_SERVE ...
- JS的String()、toString()、valueOf()的一些隐秘特性
toString()方法 要把一个值转换为一个字符串,最常用的就是,使用几乎每个值都有的toString()方法,这个方法唯一要做的就是返回相应值的字符串表现. 数值.布尔值.对象和字符串值(没错,每 ...
- 剑指offer---05---用栈实现队列
题意 给了两个栈去实现队列 分析 两个栈如下情况 1 2 4 3 这个时候就不能够把4插入到第二个弹出栈了否则弹出顺序出错. 所以这个时候就应该等第二个栈空了的时候再 ...
- P1465 序言页码 Preface Numbering (手推)
题目描述 一类书的序言是以罗马数字标页码的.传统罗马数字用单个字母表示特定的数值,以下是标准数字表: I 1 V 5 X 10 L 50 C 100 D 500 M 1000 最多3个同样的可以表示为 ...
- Python (深浅拷贝)
1.深拷贝 --> 克隆一份,修改拷贝后的内容不对原对象内容产生影响 拷贝后修改序列中元素内容,注意:被修改的元素不能为一个序列中的某个值 a = [["北京多测师",& ...
- session与cookie的浅谈
cookie的用途: 当你浏览网页时,会有一些推送消息,大多数是你最近留意过的同类东西,比如你想买桌子,上淘宝搜了一下,结果连着几天会有各种各样的桌子的链接.这是因为你浏览某个网页的时候,WEB 服务 ...
- Linux安装Git-两种方式详细教程)
一.Git介绍 Git --- The stupid content tracker, 傻瓜内容跟踪器.Linus Torvalds 是这样给我们介绍 Git 的. Git 是用于 Linux内核开发 ...
- andorid jar/库源码解析
前言 本篇作为开篇,会大体上说明,需要解读源码的,类库,或者jar. 序 原本,类库和jar的系列准备写到逆向系列课程的,但是那个东西,在写了两篇,就没有后续了,现在也不知道从哪里开始了, 只能等后期 ...