前言

去年在数据结构(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最短路径算法 教学示范代码出现重大问题!的更多相关文章

  1. Java邻接表表示加权有向图,附dijkstra最短路径算法

    从A到B,有多条路线,要找出最短路线,应该用哪种数据结构来存储这些数据. 这不是显然的考查图论的相关知识了么, 1.图的两种表示方式: 邻接矩阵:二维数组搞定. 邻接表:Map<Vertext, ...

  2. 练习 Dijkstra 最短路径算法。

    练习 Dijkstra 最短路径算法. #coding: utf-8 # Author: woodfox, Oct 14, 2014 # http://en.wikipedia.org/wiki/Di ...

  3. 一篇文章讲透Dijkstra最短路径算法

    Dijkstra是典型最短路径算法,计算一个起始节点到路径中其他所有节点的最短路径的算法和思想.在一些专业课程中如数据结构,图论,运筹学等都有介绍.其思想是一种基础的求最短路径的算法,通过基础思想的变 ...

  4. Python 图_系列之纵横对比 Bellman-Ford 和 Dijkstra 最短路径算法

    1. 前言 因无向.无加权图的任意顶点之间的最短路径由顶点之间的边数决定,可以直接使用原始定义的广度优先搜索算法查找. 但是,无论是有向.还是无向,只要是加权图,最短路径长度的定义是:起点到终点之间所 ...

  5. Dijkstra最短路径算法[贪心]

    Dijkstra算法的标记和结构与prim算法的用法十分相似.它们两者都会从余下顶点的优先队列中选择下一个顶点来构造一颗扩展树.但千万不要把它们混淆了.它们解决的是不同的问题,因此,所操作的优先级也是 ...

  6. Dijkstra 最短路径算法 秒懂详解

    想必大家一定会Floyd了吧,Floyd只要暴力的三个for就可以出来,代码好背,也好理解,但缺点就是时间复杂度高是O(n³). 于是今天就给大家带来一种时间复杂度是O(n²),的算法:Dijkstr ...

  7. Dijkstra最短路径算法实例

    #include <stdio.h>#include <stdlib.h>/* Dijkstra算法 */#define VNUM 5#define MV 65536int P ...

  8. 关于Dijkstra最短路径算法

    Dijkstra算法,不是很明白,今天找了一些博客看了一下,决定自己也写一个为以后忘记的时候可以看做准备. 实际上,如果理解没错的话,该算法实际上和枚举法有点像,只不过,在选取出发路径的路径都是最短路 ...

  9. SRM 583 Div II Level Three:GameOnABoard,Dijkstra最短路径算法

    题目来源:http://community.topcoder.com/stat?c=problem_statement&pm=12556 用Dijkstra实现,之前用Floyd算法写了一个, ...

随机推荐

  1. swift文件调用oc分类时崩溃解决办法(可能全网唯一)

    背景 oc为基础创建的sdk混编工程,在被sdk关联的混编demo工程中swift文件调用时,会崩溃,提示找不到sdk中oc分类方法.常规的,在demo中设置-Objc和-all_load也还是会崩. ...

  2. 【网站公告】避免反对百度的限制措施:百度搜索过来的访问会自动禁用js权限

    今天下午百度联系我们,发现通过百度搜索访问我们网站的博文时会出现下面反对百度的画面,让我们今天彻底处理好,保证不再出现这种情况. 我们排查后发现是这位博主申请了js权限,添加了下面的反对百度的脚本: ...

  3. RHCSA_DAY08

    locate与find查找 locate:/var/lib/mlocate/mlocate.db getfacl 目录 chmod权限管理 chmod(英文全拼:change mode)设置用户对文件 ...

  4. Http Request Smuggling - Note

    http请求走私漏洞 访问Burp靶场速度感人..都要哭了(如果没有账户的先创建账户) 基础补充 pipeline http1.1有了Pipeline,就不需要等待Server端的响应了.浏览器默认不 ...

  5. 用 Java 实现常见的 8 种内部排序算法

    一.插入类排序 插入类排序就是在一个有序的序列中,插入一个新的关键字.从而达到新的有序序列.插入排序一般有直接插入排序.折半插入排序和希尔排序. 1. 插入排序 1.1 直接插入排序 /** * 直接 ...

  6. js绕过-前端加密绕过

    前端加密解密 目录 前端加密解密 前言 前端加密定位方法 加密绕过实例 其他情况 前言 日常我们在工作时做安全测试或者日常的漏洞挖掘中,往往会遇到请求加密,参数加密的情况,而且绝大部分都是前端加密的情 ...

  7. CentOS文件目录类语法

    目录 一.目录查看切换类 1. pwd 显示当前工作目录的绝对路径 2. ls 列出目录的内容 二.文件与目录创建删除类 1. mkdir 创建一个新目录 2. touch 创建空文件 3. rmdi ...

  8. Linux之cat tail less常见用法

    1.cat 通常查找出错误日志 cat error.log | grep 'foo' , 这时候我们还有个需求就是输出当前这个日志的前后几行: cat error.log | grep -C 10 ' ...

  9. 【Python机器学习实战】决策树和集成学习(一)

    摘要:本部分对决策树几种算法的原理及算法过程进行简要介绍,然后编写程序实现决策树算法,再根据Python自带机器学习包实现决策树算法,最后从决策树引申至集成学习相关内容. 1.决策树 决策树作为一种常 ...

  10. 六种方式,教你在SpringBoot初始化时搞点事情!

    前言 在实际工作中总是需要在项目启动时做一些初始化的操作,比如初始化线程池.提前加载好加密证书....... 那么经典问题来了,这也是面试官经常会问到的一个问题:有哪些手段在Spring Boot 项 ...