数据结构(c++)(第二版) Dijkstra最短路径算法 教学示范代码出现重大问题!
前言
去年在数据结构(c++)的Dijkstra教学算法案例中,发现了一个 bug 导致算法不能正常的运行,出错代码只是4行的for循环迭代代码。
看到那里就觉得有问题,但书中只给了关键代码的部分,其余皆是伪代码,做伪代码实现,运行了教学代码,证实了相关错误。也给出了能正确运行的for循环迭代代码。
之后便将过程发给出版社,可一年多了,出版社也没有回信......

也希望大家也可以讨论一下。
Dijkstra最短路径算法
Dijkstra最路径算法用于求单源点最短路径问题,问题描述如下:给定带权有向图G=(V,E)和源点v属于V,求从v到G中其余各顶点的最短路径。
单源点最短路径问题的一个应用实例是关于计算机网络传输的问题:怎样找到一种最经济的方式,从一台计算机向网上所有其他计算机发送一条消息。
Dijkstra算法是应用贪心法进行算法设计的一个典型例子。
问题
数据结构(c++)(第二版) 版次:2011年6月第2版 印次:2020年1月第25次印刷 清华大学出版社
书中的Dijkstra的实列代码(P170-171)出现了'k'无法更新的错误,代码无法得到最后的正确结果。
'k'是dist[n]中最小值的下标,所以每次'k'的更新都要从S集合之外去寻找,而书中是以 k=0 去更新,在k=0的条件约束下,根本无法进入k的更新,所以在运行了4次之后会退出while() 没有办法更新。
希望贵出版社能够思考,若确实有错误希望贵出版社能够修正此代码。

#include <iostream>
#include <cstring>
using namespace std;
const int Max=9999;
class MGraph
{
int arc[5][5]; //邻接矩阵
string vertex[10]; //图的顶点
int vertexNum;
public:
MGraph(); //初始化邻接矩阵 对角元素为0 其他元素为Max
void Input(); //输入书中的 6 -28 进行测试
void Show();
friend void Dijkastra( MGraph G , int v );
};
MGraph::MGraph()
{
int i,j;
vertexNum=5;
vertex[0]='a'; //等同于 V0
vertex[1]='b';
vertex[2]='c';
vertex[3]='d';
vertex[4]='e';
vertex[5]='\0';
for(i=0;i<5;i++)
{
for(j=0;j<5;j++)
{
arc[i][j]=Max;
if(i==j) arc[i][j]=0;
}
}
}
void MGraph::Input()
{
int i,j,d;
cout<<"请按顺序输入 本书 图 6-28 (b)邻接矩阵的 行 列 权值 输入的行列大于等于5退出"<<endl;
cin>>i>>j>>d;
while((i<5)&&(j<5))
{
arc[i][j]=d;
cout<<"请按顺序输入 邻接矩阵的 行 列 权值"<<endl;
cin>>i>>j>>d;
}
}
void MGraph::Show()
{
int i,j;
for(i=0;i<5;i++)
{
for(j=0;j<5;j++)
{
cout<<arc[i][j]<<" ";
}
cout<<endl;
}
}
void Dijkastra( MGraph G , int v )
{
int i=0,k;
int dist[10];
int s[5];
int num;
string path[10];
for (i=0; i<G.vertexNum; i++)
{
dist[i]=G.arc[v][i];
if (dist[i]!=Max) path[i]=G.vertex[v]+G.vertex[i];
else path[i]="";
}
s[0]=v; //初始化集合 S
dist[v]=0; //标记顶点 v 为源点
num=1;
while(num<G.vertexNum) //当顶点数num小于图的顶点数
{
// 使用时 这两个for循环使用其中一个 即可得到对应结果
// 可以成功实现的迭代代码
/*for(i=0;i<G.vertexNum;i++) //修改后的 k 的迭代 *************************************
{
if(dist[i]!=0)
{
k=i;
break;
}
}*/
// 书中的教学代码
for(i=0;i<G.vertexNum;i++) //在dist中查找最小元素 ** k 无法更新!
{
if((dist[i]!=0)&&(dist[i]<dist[k])) k=i;
}
cout<<dist[k]<<" "<<path[k]<<endl;
s[num++]=k; //将生成的重点加入集合S
for(i=0;i<G.vertexNum;i++) //修改数组dist和path
{
if(dist[i]>dist[k]+G.arc[k][i])
{
dist[i]=dist[k]+G.arc[k][i];
path[i]=path[k]+G.vertex[i];
}
}
dist[k]=0; //置顶点k 为已生成顶点标记
}
}
int main(int argc, char** argv)
{
MGraph G;
G.Input();
G.Show();
Dijkastra(G,0);
return 0;
}
改正后的代码

教材示例代码

数据结构(c++)(第二版) Dijkstra最短路径算法 教学示范代码出现重大问题!的更多相关文章
- Java邻接表表示加权有向图,附dijkstra最短路径算法
从A到B,有多条路线,要找出最短路线,应该用哪种数据结构来存储这些数据. 这不是显然的考查图论的相关知识了么, 1.图的两种表示方式: 邻接矩阵:二维数组搞定. 邻接表:Map<Vertext, ...
- 练习 Dijkstra 最短路径算法。
练习 Dijkstra 最短路径算法. #coding: utf-8 # Author: woodfox, Oct 14, 2014 # http://en.wikipedia.org/wiki/Di ...
- 一篇文章讲透Dijkstra最短路径算法
Dijkstra是典型最短路径算法,计算一个起始节点到路径中其他所有节点的最短路径的算法和思想.在一些专业课程中如数据结构,图论,运筹学等都有介绍.其思想是一种基础的求最短路径的算法,通过基础思想的变 ...
- Python 图_系列之纵横对比 Bellman-Ford 和 Dijkstra 最短路径算法
1. 前言 因无向.无加权图的任意顶点之间的最短路径由顶点之间的边数决定,可以直接使用原始定义的广度优先搜索算法查找. 但是,无论是有向.还是无向,只要是加权图,最短路径长度的定义是:起点到终点之间所 ...
- Dijkstra最短路径算法[贪心]
Dijkstra算法的标记和结构与prim算法的用法十分相似.它们两者都会从余下顶点的优先队列中选择下一个顶点来构造一颗扩展树.但千万不要把它们混淆了.它们解决的是不同的问题,因此,所操作的优先级也是 ...
- Dijkstra 最短路径算法 秒懂详解
想必大家一定会Floyd了吧,Floyd只要暴力的三个for就可以出来,代码好背,也好理解,但缺点就是时间复杂度高是O(n³). 于是今天就给大家带来一种时间复杂度是O(n²),的算法:Dijkstr ...
- Dijkstra最短路径算法实例
#include <stdio.h>#include <stdlib.h>/* Dijkstra算法 */#define VNUM 5#define MV 65536int P ...
- 关于Dijkstra最短路径算法
Dijkstra算法,不是很明白,今天找了一些博客看了一下,决定自己也写一个为以后忘记的时候可以看做准备. 实际上,如果理解没错的话,该算法实际上和枚举法有点像,只不过,在选取出发路径的路径都是最短路 ...
- SRM 583 Div II Level Three:GameOnABoard,Dijkstra最短路径算法
题目来源:http://community.topcoder.com/stat?c=problem_statement&pm=12556 用Dijkstra实现,之前用Floyd算法写了一个, ...
随机推荐
- 开源ERP和其它ERP软件比较
现在有许多企业将ERP项目,在企业中没有实施好,都归咎于软件产品不好.其实,这只是你们的借口.若想要将ERP软件真正与企业融合一体,首先得考虑企业的自身情况,再去选择适合的 ERP软件. 如果你的企业 ...
- 记录21.08.04 — mybatis入门学习
mybatis入门 mybatis简介 MyBatis 是一款优秀的持久层框架,它支持自定义 SQL.存储过程以及高级映射.MyBatis 免除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工 ...
- Jenkins自动化部署最完整教程
1.概述 Jenkins 是一个可扩展的持续集成引擎.主要用于持续.自动地构建/测试软件项目.监控一些定时执行的任务.Jenkins用Java语言编写,可在Tomcat等流行的servlet容器中运行 ...
- EL表达式和JSTL标签
什么是 EL 表达式,EL 表达式的作用? EL 表达式的全称是:Expression Language.是表达式语言. EL 表达式的什么作用:EL 表达式主要是代替 jsp 页面中的表达式脚本在 ...
- 十分钟带你了解CANN应用开发全流程
摘要:CANN作为昇腾AI处理器的发动机,支持业界多种主流的AI框架,包括MindSpore.TensorFlow.Pytorch.Caffe等,并提供1200多个基础算子. 2021年7月8日,第四 ...
- WPF自定义控件一:StackPanel 控件轮播
实现效果 带定时器的轮播图 using引用 using System.Windows; using System.Windows.Controls; using System.Windows.Mark ...
- Java调用阿里云短信接口发送手机验证码
前五步可参考阿里云服务文档:https://help.aliyun.com/document_detail/59210.html?spm=a2c4g.11174283.4.1.2b152c42DoJ7 ...
- PHP随手记2--获取随机n位不重复字符
定义一个函数返回26英文字母中n位不重复随机字符 基本思路是利用内置函数生成随机数,取出该位置字母之后将其删除,再进行下一次随机,最后实现字符串拼接就ok! 代码很简单,通俗易懂,直接上代码吧: 1 ...
- 自定义Vue&Element组件,实现用户选择和显示
在我们很多前端业务开发中,往往为了方便,都需要自定义一些用户组件,一个是减少单一页面的代码,提高维护效率:二个也是方便重用.本篇随笔介绍在任务管理操作中,使用自定义Vue&Element组件, ...
- WPF 中的 button style 的修改
<Style x:Key="ButtonStyleTransBack" TargetType="Button"> <Setter Proper ...