Dijkstra算法的C++实现


看过老严的《数据结构》中关于Dijkstra算法的描述后,觉得她给的伪代码不好理解,自己根据算法的描述用C++实现了自己的Dijkstra算法.

其中在实现算法的过程中遇到两个问题:
(1)如何将二维数组作为参数传入函数?
  在网上搜到很多,采用的方法如下
  1.函数中使用 int ** pMatrix, pMatrix指向图的临接矩阵
  2.还要指明矩阵的结构:
 for (int i=0; i < VexNum; i++)
 {
  pBandMatrix[i] = BandMatrix[i];  
 }
     pBandMatrix就可以作为第一个参数传入函数
void ShortestPath_Dijkstra(int **pMatrix, int SrcVex, int *Distance, string *PathString)
  关于二维数组传参的信息可以参考:
http://blog.csdn.net/xuleicsu/archive/2006/07/14/919801.aspx
(2)使用到itoa函数将int型转换char型
itoa函数原型
#include <stdlib.h>
char *itoa(int value, char *string, int radix)
函数用途:将整型数value转换为其等价的字符串
itoa将int型的value转换为char后,存入char p[]数组中,这个时候要注意:
如果value=12,p[0]='1',p[1]='2',p[2]='/0'
如果定义为:char p[2];显然,这个时候回产生数组越界,然后报错:
Run-Time Check Failure #2 - Stack around the variable 'p' was corrupted.

实现的程序如下:
(1)GraphData.h
#ifndef GRAPHDATA_H
#define GRAPHDATA_H

const int INF=10000;
const int VexNum=18;
int *pBandMatrix[18];
int *pCostMatrix[18];
int *pDelayMatrix[18];
/************************************************************************/
/* 临接矩阵                                                                     */
/************************************************************************/

//带宽矩阵
int BandMatrix[VexNum][VexNum]={{INF,6,10,20,INF,INF,INF,INF,INF,INF,INF,INF,INF,INF,INF,INF,INF,INF},
        {6,INF,INF,INF,23,INF,INF,INF,INF,INF,INF,INF,INF,INF,INF,INF,INF,INF},
        {10,INF,INF,INF,INF,12,4,INF,INF,INF,INF,INF,1,INF,INF,INF,INF,INF},
        {20,INF,INF,INF,INF,INF,INF,13,20,INF,INF,INF,INF,INF,INF,INF,INF,INF},
        {INF,23,INF,INF,INF,30,INF,INF,INF,6,INF,INF,INF,INF,INF,INF,INF,INF},
        {INF,INF,12,INF,30,INF,INF,INF,INF,INF,INF,INF,INF,INF,INF,INF,INF,INF},
        {INF,INF,4,INF,INF,INF,INF,INF,INF,INF,INF,INF,INF,20,INF,INF,INF,INF},
        {INF,INF,INF,13,INF,INF,INF,INF,INF,INF,INF,INF,INF,19,INF,INF,INF,INF},
        {INF,INF,INF,20,INF,INF,INF,INF,INF,INF,INF,INF,INF,12,INF,INF,INF,INF},
        {INF,INF,INF,INF,6,INF,INF,INF,INF,INF,4,INF,INF,INF,21,34,INF,INF},
        {INF,INF,INF,INF,INF,INF,INF,INF,INF,4,INF,10,INF,INF,INF,INF,INF,INF},
        {INF,INF,INF,INF,INF,INF,INF,INF,INF,INF,11,INF,21,INF,INF,INF,INF,INF},
        {INF,INF,1,INF,INF,INF,INF,INF,INF,INF,INF,21,INF,2,INF,INF,INF,INF},
        {INF,INF,INF,INF,INF,INF,20,19,12,INF,INF,INF,2,INF,14,INF,INF,INF},
        {INF,INF,INF,INF,INF,INF,INF,INF,INF,21,INF,INF,INF,14,INF,INF,INF,1},
        {INF,INF,INF,INF,INF,INF,INF,INF,INF,34,INF,INF,INF,INF,INF,INF,5,INF},
        {INF,INF,INF,INF,INF,INF,INF,INF,INF,INF,INF,INF,INF,INF,INF,5,INF,4},
        {INF,INF,INF,INF,INF,INF,INF,INF,INF,INF,INF,INF,INF,INF,1,INF,4,INF}};

//费用矩阵
int CostMatrix[VexNum][VexNum]={{INF,4,2,1,INF,INF,INF,INF,INF,INF,INF,INF,INF,INF,INF,INF,INF,INF},
        {4,INF,INF,INF,1,INF,INF,INF,INF,INF,INF,INF,INF,INF,INF,INF,INF,INF},
        {2,INF,INF,INF,INF,9,1,INF,INF,INF,INF,INF,3,INF,INF,INF,INF,INF},
        {1,INF,INF,INF,INF,INF,INF,4,1,INF,INF,INF,INF,INF,INF,INF,INF,INF},
        {INF,1,INF,INF,INF,1,INF,INF,INF,9,INF,INF,INF,INF,INF,INF,INF,INF},
        {INF,INF,1,INF,9,INF,INF,INF,INF,INF,INF,INF,INF,INF,INF,INF,INF,INF},
        {INF,INF,1,INF,INF,INF,INF,INF,INF,INF,INF,INF,INF,1,INF,INF,INF,INF},
        {INF,INF,INF,4,INF,INF,INF,INF,INF,INF,INF,INF,INF,1,INF,INF,INF,INF},
        {INF,INF,INF,1,INF,INF,INF,INF,INF,INF,INF,INF,INF,4,INF,INF,INF,INF},
        {INF,INF,INF,INF,9,INF,INF,INF,INF,INF,1,INF,INF,INF,1,2,INF,INF},
        {INF,INF,INF,INF,INF,INF,INF,INF,INF,1,INF,2,INF,INF,INF,INF,INF,INF},
        {INF,INF,INF,INF,INF,INF,INF,INF,INF,INF,2,INF,2,INF,INF,INF,INF,INF},
        {INF,INF,3,INF,INF,INF,INF,INF,INF,INF,INF,2,INF,3,INF,INF,INF,INF},
        {INF,INF,INF,INF,INF,INF,1,1,4,INF,INF,INF,3,INF,2,INF,INF,INF},
        {INF,INF,INF,INF,INF,INF,INF,INF,INF,1,INF,INF,INF,2,INF,INF,INF,1},
        {INF,INF,INF,INF,INF,INF,INF,INF,INF,2,INF,INF,INF,INF,INF,INF,3,INF},
        {INF,INF,INF,INF,INF,INF,INF,INF,INF,INF,INF,INF,INF,INF,INF,3,INF,1},
        {INF,INF,INF,INF,INF,INF,INF,INF,INF,INF,INF,INF,INF,INF,1,INF,1,INF}};
//延迟矩阵
int DelayMatrix[VexNum][VexNum]={{INF,70,60,80,INF,INF,INF,INF,INF,INF,INF,INF,INF,INF,INF,INF,INF,INF},
         {70,INF,INF,INF,90,INF,INF,INF,INF,INF,INF,INF,INF,INF,INF,INF,INF,INF},
         {60,INF,INF,INF,INF,80,70,INF,INF,INF,INF,INF,95,INF,INF,INF,INF,INF},
         {80,INF,INF,INF,INF,INF,INF,60,100,INF,INF,INF,INF,INF,INF,INF,INF,INF},
         {INF,90,INF,INF,INF,70,INF,INF,INF,80,INF,INF,INF,INF,INF,INF,INF,INF},
         {INF,INF,80,INF,70,INF,INF,INF,INF,INF,INF,INF,INF,INF,INF,INF,INF,INF},
         {INF,INF,70,INF,INF,INF,INF,INF,INF,INF,INF,INF,INF,60,INF,INF,INF,INF},
         {INF,INF,INF,60,INF,INF,INF,INF,INF,INF,INF,INF,INF,70,INF,INF,INF,INF},
         {INF,INF,INF,100,INF,INF,INF,INF,INF,INF,INF,INF,INF,80,INF,INF,INF,INF},
         {INF,INF,INF,INF,80,INF,INF,INF,INF,INF,70,INF,INF,INF,80,100,INF,INF},
         {INF,INF,INF,INF,INF,INF,INF,INF,INF,70,INF,90,INF,INF,INF,INF,INF,INF},
         {INF,INF,INF,INF,INF,INF,INF,INF,INF,INF,90,INF,60,INF,INF,INF,INF,INF},
         {INF,INF,95,INF,INF,INF,INF,INF,INF,INF,INF,60,INF,80,INF,INF,INF,INF},
         {INF,INF,INF,INF,INF,INF,60,70,80,INF,INF,INF,80,INF,70,INF,INF,INF},
         {INF,INF,INF,INF,INF,INF,INF,INF,INF,80,INF,INF,INF,70,INF,INF,INF,100},
         {INF,INF,INF,INF,INF,INF,INF,INF,INF,100,INF,INF,INF,INF,INF,INF,70,INF},
         {INF,INF,INF,INF,INF,INF,INF,INF,INF,INF,INF,INF,INF,INF,INF,70,INF,60},
         {INF,INF,INF,INF,INF,INF,INF,INF,INF,INF,INF,INF,INF,INF,100,INF,60,INF}};

#endif

(2)Dijkstra.cpp主文件

#include "stdafx.h"
#include "GraphData.h"
#include <string>

//所有的顶点集为V,已经求得到源节点最短路径的点集为S

//求出点SrcVex到所有不在S中点的直接距离最短的点
int ShortestVexToVex(int **pMatrix, int SrcVex, bool *Final)   
{
 int min = INF,k=-1;
 for (int v=0; v < VexNum; v++)
 {
  if (!Final[v])    //点v不在S集中
  {
   if (pMatrix[SrcVex][v] < min)
   {
    k = v;
    min = pMatrix[SrcVex][v];
   }
  }
      
 }
 return k;
}

/*pMatrix指向图的临接矩阵
  SrcVex源节点
  Distance数组记录SrcVex点到其他各点的最短距离
  PathString为string数组,记录SrcVex点到其他各点的最短路径*/
void ShortestPath_Dijkstra(int **pMatrix, int SrcVex, int *Distance, string *PathString)
{
 bool Final[VexNum];  //当Final[v]=True时,表示已经求得源节点到v得最短路径

 //初始化数组
 for (int v=0; v < VexNum; v++)
 {
  Final[v] = false;
  Distance[v]=pMatrix[SrcVex][v];  
 }

 Distance[SrcVex] = 0;
 Final[SrcVex] = true; //把源节点加入S集中


 int min1 = INF,k = 0,StartVex=0,EndVex=0, min2 = INF;
 char p[3];   //用来把点的数字代码转换为字符型

 //求从源节点SrcVex出发的最短路径
 for (int i=1; i < VexNum; i++)
 {
  //求不在S集中,与SrcVex点距离最短的点,最短距离存入min1
  min1 = INF;  
  for (int v=0; v < VexNum; v++)
  {
   
   if (!Final[v])                //v不在S中
   {
    if (Distance[v] < min1)
    {
     k = v;
     min1 = Distance[v];
    }
   }
          
  }

  //求SrcVex点,与V-S中点直接相连的最短路径,
  min2 = INF;
  for (int w=0; w < VexNum; w++)
  {   
   if (Final[w])              //w在S中
   {
    if (pMatrix[w][ShortestVexToVex(pMatrix,w,Final)] + Distance[w]< min2 && ShortestVexToVex(pMatrix,w,Final)>-1)
    {
     StartVex = w;
     EndVex = ShortestVexToVex(pMatrix,w,Final);     
     min2 = pMatrix[StartVex][EndVex] + Distance[StartVex];
    }
   }
  }
  //min2 = pMatrix[StartVex][EndVex] + Distance[StartVex];
  if (min1 > min2 )
  {
   Distance[EndVex] = min2;
   Final[EndVex] = true;   //加入S集中
   itoa(EndVex,p,10);
   PathString[EndVex]=PathString[StartVex]+"->";
   PathString[EndVex]+= p[0];

   if (p[1] != '/0')
   {
    PathString[EndVex]+=p[1];
   }   
  }
  else
  {
   Distance[k] = min1;
   Final[k] = true;
   
   itoa(SrcVex,p,10);
   PathString[k] +=p[0];
   if (p[1] != '/0')
   {
    PathString[k] += p[1];
   }

   itoa(k,p,10);
   PathString[k] += "->";
   PathString[k] += p[0];  
   
   if (p[1] != '/0')
   {
    PathString[k]+=p[1];
   }
  }  
 }
}

int _tmain(int argc, _TCHAR* argv[])
{
   
 for (int i=0; i < VexNum; i++)
 {
  pBandMatrix[i] = BandMatrix[i];
  pCostMatrix[i] = CostMatrix[i];
  pDelayMatrix[i] = DelayMatrix[i];
 }

 int Distance[VexNum];
 string Path[VexNum];
 for (int i=0; i < VexNum; i++)
 {
  Path[i]="";
 }
 ShortestPath_Dijkstra(pBandMatrix,0,Distance,Path);
 for (int i = 0; i < VexNum ; i++)
 {
  cout << Distance[i]<<":"<<Path[i]<< endl;
 } 

 system("pause");
 return 0;
}

输出结果:

 

       
 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Dijkstra算法是一种用于解决单源最短路径问题的经典算法。下面是Dijkstra算法C++代码实现: ```cpp #include <iostream> #include <vector> #include <queue> #include <climits> using namespace std; // 定义图的邻接表表示 typedef pair<int, int> pii; typedef vector<vector<pii>> Graph; // Dijkstra算法实现 vector<int> dijkstra(const Graph& graph, int start) { int n = graph.size(); vector<int> dist(n, INT_MAX); // 存储起点到各个顶点的最短距离 vector<bool> visited(n, false); // 记录顶点是否已访问 priority_queue<pii, vector<pii>, greater<pii>> pq; // 小顶堆,存储顶点和距离的pair dist[start] = 0; // 起点到自身的距离为0 pq.push(make_pair(0, start)); while (!pq.empty()) { int u = pq.top().second; pq.pop(); if (visited[u]) { continue; } visited[u] = true; for (const auto& neighbor : graph[u]) { int v = neighbor.first; int weight = neighbor.second; if (dist[u] + weight < dist[v]) { dist[v] = dist[u] + weight; pq.push(make_pair(dist[v], v)); } } } return dist; } int main() { int n, m; // n为顶点数,m为边数 cin >> n >> m; Graph graph(n); for (int i = 0; i < m; ++i) { int u, v, weight; cin >> u >> v >> weight; graph[u].push_back(make_pair(v, weight)); graph[v].push_back(make_pair(u, weight)); } int start; cin >> start; vector<int> shortestDist = dijkstra(graph, start); for (int i = 0; i < n; ++i) { cout << "Shortest distance from " << start << " to " << i << " is " << shortestDist[i] << endl; } return 0; } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值