数据结构(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算法写了一个, ...
随机推荐
- WPF DataGrid DataGridTextColumn
Style设置时,无法绑定到数据,需要这样写 1 <DataGridTextColumn Header="呵呵" Binding="{Binding ID}&quo ...
- Python中比较运算符连用的语法规则
在Python中,比较运用符<.>.<=.>=.== .!=可以连用,但语法规则和其它编程语言不一样 以 == 为例,具体语法规则是: a == b == c == d 等价于 ...
- Solidity
起因是Xenc师傅给我截了张图,我日 居然看不懂 ,一搜才知道,之前学的版本有些老了.. 这次学下新一点的记录下 HelloWorld pragma solidity ^0.6.0; // versi ...
- RedisTemplate连接不释放、Redis断线不重连问题、Redis连接数高飙升
使用RedisTemplate操作Redis数据,但遇到网络断线后不会重新连接 毫无头绪 一顿捣鼓 最终解决 整理如下 帮助更多的人 1.起因 使用RedisTemplate 配置 开启了事务 ena ...
- 小知识get:利用单臂路由实现不同vlan间路由
一.单臂路由概述 1.1.单臂路由实现不同vlan间通信 链路类型 交换机连接主机的端口为access链路 交换机连接路由器的端口为Trunk链路 子接口 路由器的物理接口可以被划分成多个逻辑接口 每 ...
- PHPMailer 远程命令执行漏洞 Writeup
漏洞概述 1.漏洞简介 PHPMailer 小于5.2.18的版本存在远程代码执行漏洞.成功利用该漏洞后,攻击者可以远程任意代码执行.许多知名的 CMS 例如 Wordpress 等都是使用这个组件来 ...
- Java之JSTL标签与JavaBean
Java之JSTL标签与JavaBean JSP.JSTL标签及 EL表达式 <!-- jstl表达式--> <dependency> <groupId>javax ...
- miniFTP项目实战四
项目简介: 在Linux环境下用C语言开发的Vsftpd的简化版本,拥有部分Vsftpd功能和相同的FTP协议,系统的主要架构采用多进程模型,每当有一个新的客户连接到达,主进程就会派生出一个ftp服务 ...
- NOIP 模拟 $13\; \text{玄学题}$
题解 题如其名,是挺玄学的. 我们发现每个值是 \(-1\) 还是 \(1\) 只与它的次数是奇是偶有关,而 \(\sum_j^{j\le m}d(i×j)\) 又只与其中有多少个奇数有关 对于 \( ...
- .Net Core 踩坑记录--无法逐步调试类库文件
前提 新建类库 在新项目中引用该类库 将类库对应的.PDB文件 拷贝至新项目的bin文件夹下 结果 无法进行跟踪调试 狗带 分析与解决 1: 打开 工具-->选项-->调试 2: 常规-- ...