• linkedu视频
  • 平面设计
  • 电脑入门
  • 操作系统
  • 办公应用
  • 电脑硬件
  • 动画设计
  • 3D设计
  • 网页设计
  • CAD设计
  • 影音处理
  • 数据库
  • 程序设计
  • 认证考试
  • 信息管理
  • 信息安全
菜单
linkedu.com
  • 网页制作
  • 数据库
  • 程序设计
  • 操作系统
  • CMS教程
  • 游戏攻略
  • 脚本语言
  • 平面设计
  • 软件教程
  • 网络安全
  • 电脑知识
  • 服务器
  • 视频教程
  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号
您的位置:首页 > 程序设计 >C语言 > C++用Dijkstra(迪杰斯特拉)算法求最短路径

C++用Dijkstra(迪杰斯特拉)算法求最短路径

作者: 字体:[增加 减小] 来源:互联网 时间:2017-05-28

通过本文主要向大家介绍了dijkstra 迪杰斯特拉,迪杰斯特拉,迪杰斯特拉算法,迪杰斯特拉最短路径,迪杰斯特拉算法思想等相关知识,希望对您有所帮助,也希望大家支持linkedu.com www.linkedu.com

算法介绍

迪杰斯特拉算法是由荷兰计算机科学家狄克斯特拉于1959 年提出的,因此又叫狄克斯特拉算法。是从一个顶点到其余各顶点的最短路径算法,解决的是有向图中最短路径问题。迪杰斯特拉算法主要特点是以起始点为中心向外层层扩展,直到扩展到终点为止。Dijkstra算法能得出最短路径的最优解,但由于它遍历计算的节点很多,所以效率低。

算法思想

按路径长度递增次序产生算法:

 把顶点集合V分成两组:

  (1)S:已求出的顶点的集合(初始时只含有源点V0)

  (2)V-S=T:尚未确定的顶点集合
  将T中顶点按递增的次序加入到S中,保证:

  (1)从源点V0到S中其他各顶点的长度都不大于从V0到T中任何顶点的最短路径长度

  (2)每个顶点对应一个距离值

  S中顶点:从V0到此顶点的长度

  T中顶点:从V0到此顶点的只包括S中顶点作中间顶点的最短路径长度

  依据:可以证明V0到T中顶点Vk的,或是从V0到Vk的直接路径的权值;或是从V0经S中顶点到Vk的路径权值之和

应用举例

(1)题目:编写一个校园导游程序,为来访的客人提供各种信息查询服务。

    主要功能:1.设计学校的校园平面图,所含景点不少于10个:顶点表示景点,边表示路径等;

         2.为客人提供图中任意景点相关信息的查询;

         3.为客人提供图中任意景点的问路查询,即查询人以景点间的一条最短路径。

      要求:1.设计一个主界面;

              2.设计功能菜单,供用户选择

              3.有一定的实用性。

(2)设计思路:

  1、该题主要有算法思路以及程序的逻辑思路,首先从逻辑思路讲,进入程序,首先设计一个主菜单,选项有景点信息查询,最短路径查询以及显示景点的平面视图三个子菜单,然后根据用户的输入选择的子菜单前的编号,分进入不同的子菜单;该功能是由if….else if…. 语句实现。在景点信息查询和最短路径查询子菜单下还有二级子菜 单,都是列 出所有景点并在前面编号,查询景点信息时,输入景点前面的编号即可,查询最短路径时,先输入起点的编号,再输入终点的编号。而显示景点视图则调用景点平面图函数即可显 示。

  2、算法思路主要是迪杰斯特拉算法的思路,利用迪杰斯特拉算法求最短路径。

  3、先定义好图的储存结构,本题采用邻接矩阵的方式来表示图,并在主函数中初始化该图;

  4、定义三个全局一维数组,一个bool类型数组S[]用来记录从v0到vi是否已经确定了最短路径,是则记S[i]=true ,否记S[i]= flase;一个int 类型数组Path[]用来记录从v0到vi的当前最短路径上的vi的直接前驱顶点编号,若v 到vi之间有边则记Path[i] = v的编号,否则记Path[i] = -1;最后一个数组D[]用来记录从v0到vi之间的最短路径长度,存在则记v0到vi之间边的权值或者权值和,否则记为MAX

  5、定义一个求最短路径的函数,传入的参数为图和起点,首先进行初始化工作,初始化S[]数组全为false,D[]数组初始化为起点到各个顶点的权值,Path[]数组初始化为起点是否与各顶点有边,有则记v0否则记-1;

  6、然后进行n-1次for循环,找出vo到其余n-1个顶点之间的最短路径,比较当前D[]数组中最小值,找到最小值的编号v,该编号就是从v0出发到所有顶点中距离最短的顶点编号,然后把S[v]的值置为true。说明从v0出发到顶点v已经找到最短路径;

  7、接着就要更新D[]数组,因为D[]数组是记录最短路径的,现在已经找到了一个顶点的最短路径,已该顶点v为中间点,判断从该顶点v出发到剩下的顶点的路径长度加上该点到v0的路径长度是否小于直接从v0出发到其余顶点的路径长度,如果小于,则更新D[i]为以该顶点v为中间点求得的路径长度。更新Path[i] = v;即i的前驱不再是v0而是v;

  8、循环(6)(7)两步n-1次即可得到D[]数组,输出D[]数组既是v0到所有顶点的最短路径长度;

(3)源代码:

#include<iostream>
#include<fstream>
#include<string>
using namespace std;
/**
 *作者:Dmego
 *时间:2016-12-12
 */
#define MAX 1000000 //表示极大值∞
#define max 10
bool S[max]; //记录从源点V0到终点Vi是否已经确定为最短路径,确定了记true,否则记false
int Path[max]; //记录从源点V0到终点Vi的当前最短路径上终点Vi的直接前驱顶点序号,若V0到Vi之间有边前驱为V0否则为-1 
int D[max]; //记录源点到终点之间最短路径的长度,存在记V0到Vi的边的权值,否则记为MAX 
typedef struct
{
 string vexs[max]; //顶点表
 int arcs[max][max]; //邻接矩阵 
 int vexnum, arcnum; //图当前点数和边数

}AMGraph;
//利用迪杰斯特拉算法求最短路径
void ShortestPath_DIJ(AMGraph &G, int v0)
{//使用迪杰斯特拉算法求有向网G中的V0 定点到其余顶点的最短路径
 int n = G.vexnum;//顶点数
 for (int v = 0; v < n; v++)//n个顶点依次初始化
 {
 S[v] = false;//S初始化为空集
 D[v] = G.arcs[v0][v];//将v0到各个终点的最短路径长度初始化为边上的权值
 if (D[v] < MAX)
  Path[v] = v0;//如果v0和v之间有边,则将v的前驱初始化为v0
 else
  Path[v] = -1;//如果v0和v之间无边,则将v的前驱初始化为-1
 }
 S[v0] = true; //将v0加入s
 D[v0] = 0;//源点到源点的权值为0
 //---------初始化结束,开始主循环,每次求得v0到某个顶点的最短路径,将v加到S数组
 for (int i = 1; i < n; i++)//依次对其余n-1个顶点进行计算
 {
 int min = MAX;
 int v = v0;
 for (int w = 0; w < n; w++)
 {
  if (!S[w] && D[w] < min)
  {//选择一条当前最短路径,终点为v
  v = w;
  min = D[w];
  }
  S[v] = true;//将v加到s集合中
  for (int w = 0; w < n; w++)
  {//更新从v0出发到集合V-S上所有顶点的最短路径长度
  if (!S[w] && (D[v] + G.arcs[v][w] < D[w]))
  {
   D[w] = D[v] + G.arcs[v][w];//更新D[w]
   Path[w] = v;//更改w的前驱为v
  }
  }
 }
 }
}
//背景函数
void backGround()
{
 cout << "|*****************************************************************|" << endl;
 cout << " |------------------------铁大旅游景点图-----------------|" << endl;
 cout << "|*****************************************************************|" << endl;
 cout << "|  ⑦      单位:米 |" << endl;
 cout << "|  九教       |" << endl;
 cout << "|  ◎     ⑧  |" << endl;
 cout << "|  ↗↖     九栋  |" << endl;
 cout << "| ③ 200╱ ╲     ◎  |" << endl;
 cout << "| 西 ↙ ╲ 150    ↗ ↖  |" << endl;
 cout << "| 操 ◎  ╲ ①  160 ╱ ╲ 200 |" << endl;
 cout << "| 场 ↖150  ╲ 信息  ⑥ ╱  ╲ |" << endl;
 cout << "| ④ ↘ 140 ↘ 学院 200 基教 ↙ 230 ↘ |" << endl;
 cout << "| 体育馆 ◎-------------→◎←--------------→◎←--------------→◎ |" << endl;
 cout << "|  ↖  ↗ ↖  ↗ ↖  ↗② |" << endl;
 cout << "|  100 ╲ ╱ ╲ 125 ╱ ╲ 150 ╱ 综 |" << endl;
 cout << "|  ↘ ↙ 100 ╲ ╱135 ╲ ╱145 餐 |" << endl;
 cout << "|   ◎  ↘ ↙  ↘ ↙ |" << endl;
 cout << "|  ⑨ 沁园  ◎   ◎  |" << endl;
 cout << "|    ⑩ 翠园  ⑤ 春晖楼  |" << endl;
 cout << "|        |" << endl;
 cout << "|*****************************************************************|" << endl;

}
//主菜单
void menu()
{
 cout << "|*****************************************************************|" << endl;
 cout << "|----------------------------铁大导游小程序-----------------------|" << endl;
 cout << " |*********************************************************|" << endl;
 cout << " |--------------------1-景点信息查询--------------|" << endl;
 cout << " |--------------------2-最短路径查询--------------|" << endl;
 cout << " |--------------------3-显示景点视图--------------|" << endl;
 cout << " |-------------------4-退出导游程序------ --------|" << endl;
 cout << "|*****************************************************************|" << endl;
 cout << ">>&g



 
分享到:QQ空间新浪微博腾讯微博微信百度贴吧QQ好友复制网址打印

您可能想查找下面的文章:

  • C++用Dijkstra(迪杰斯特拉)算法求最短路径

相关文章

  • 2017-05-28C语言system 自动关机函数代码
  • 2017-05-28C++位操作的常见用法小结
  • 2017-05-28VC WinExec打开指定程序或者文件的方法
  • 2017-05-28C++设计模式之状态模式
  • 2017-05-28new和malloc的区别深入解析
  • 2017-05-28用C语言实现单链表的各种操作(二)
  • 2017-05-28C++ Assert()断言机制原理以及使用方法
  • 2017-05-28C++中四种对象生存期和作用域以及static的用法总结分析
  • 2017-05-28c语言将字符串中的小写字母转换成大写字母
  • 2017-05-28c语言10个经典小程序

文章分类

  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号

最近更新的内容

    • 详解C++中的const关键字及与C语言中const的区别
    • 使用WindowsAPI获取录音音频的方法
    • C语言中对于循环结构优化的一些入门级方法简介
    • 基于欧几里德算法的使用
    • 基于堆的基本操作的介绍
    • C++非递归遍历磁盘文件和递归遍历磁盘文件的程序示例
    • C++可变参数的实现方法
    • MFC创建右键弹出菜单的方法
    • socket多人聊天程序C语言版(二)
    • Windows网络编程之winsock实现文件传输示例

关于我们 - 联系我们 - 免责声明 - 网站地图

©2020-2025 All Rights Reserved. linkedu.com 版权所有