程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> 單源最短路徑Dijkstra算法C++實現

單源最短路徑Dijkstra算法C++實現

編輯:C++入門知識

 

// 單源最短路徑Dijkstra算法實現.cpp : Defines the entry point for the console application.

//

#include "stdafx.h"

#include<iostream>

#define MAX 200

#define Infinity 65535

using namespace std;

//邊尾節點信息結構體

struct edgeNode

{

 int no;   //尾接點序號

 int cost;  //邊權值

 edgeNode *next; //其下一條鄰接邊尾節點指針

};

//節點信息結構體

struct vexNode

{

 char info;  //節點名稱

 edgeNode *link; //與其相連的邊的尾節點鏈表指針

};

struct Queue

{

 int no; //隊列中節點序號

 int cost; //以此為尾節點的邊的權值

};

//優先隊列

Queue priQue[MAX];

//節點數組

vexNode adjlist[MAX];

//指定源點到節點i的最短路徑花費

int lowcost[MAX];

//指定源點到節點i路徑中,節點i的前驅節點序號

int parent[MAX];

//建立圖鄰接表

void createGraph(vexNode *adjlist,int *parent,int * lowcost,const int n,const int e)

{

 int i;

 for(i=1;i<=n;i++)

 {

  cout<<"請輸入節點"<<i<<"的名稱:";

  cin>>adjlist[i].info;

  adjlist[i].link = NULL;

  lowcost[i] = Infinity;

  parent[i] = i;

 }

 edgeNode *p1;

   int v1,v2;

 for(i=1;i<=e;i++)

 {

  cout<<"請輸入邊"<<i<<"的起始節點與尾節點序號:";

  cin>>v1>>v2;

  p1 = (edgeNode*)malloc(sizeof(edgeNode));

  p1->no = v2;

  cout<<"此邊的權值:";

  cin>>p1->cost;

  p1->next = adjlist[v1].link;

  adjlist[v1].link = p1;

 }

}

//當插入節點到優先隊列時,保持隊列優先性

void keep_min_heap(Queue *priQue,int &num,const int k)

{

 int l = 2*k;

 int r = 2*k + 1;

 int smallest = k;

 if(l<=num&&priQue[l].cost<priQue[k].cost)

  smallest = l;

 if(r<=num&&priQue[r].cost<priQue[smallest].cost)

  smallest = r;

 if(smallest != k)

 {

  Queue temp = priQue[smallest];

  priQue[smallest] = priQue[k];

  priQue[k] = temp;

  keep_min_heap(priQue,num,smallest);

 }

}

//插入節點到優先隊列時並且保持隊列優先性

void heap_insert(Queue *priQue,int &num,int no,int cost)

{

 num +=1;

 priQue[num].no = no;

 priQue[num].cost = cost;

 int i = num;

 while(i>1&&priQue[i/2].cost>priQue[i].cost)

 {

  Queue temp = priQue[i];

  priQue[i] = priQue[i/2];

  priQue[i/2] = temp;

  i = i/2;

 }

}

//取出優先隊列的隊頭元素

Queue heap_extract_min(Queue *priQue,int &num)

{

 if(num<1)

  return priQue[0];

 Queue min = priQue[1];

 priQue[1] = priQue[num];

 num -=1;

 keep_min_heap(priQue,num,1);

 return min;

}

//打印指定源點帶序號為i的點的最短路徑

void print_it(int *parent,vexNode *adjlist,int v)

{

 if(parent[v] == v)

  cout<<"("<<v<<":"<<adjlist[v].info<<") ";

 else

 {

  print_it(parent,adjlist,parent[v]);

  cout<<"("<<v<<":"<<adjlist[v].info<<") ";

 }

}

int _tmain(int argc, _TCHAR* argv[])

{

int cases;

 cout<<"請輸入案例的個數:";

 cin>>cases;

 while(cases--)

 {

  int n,e;

  cout<<"請輸入節點數:";

  cin>>n;

  cout<<"請輸入邊數:";

  cin>>e;

  //隊列中的元素,初始為0

  int num = 0;

  int i;

  //創建鄰接表

  createGraph(adjlist,parent,lowcost,n,e);

  cout<<endl;

  cout<<"從哪個節點開始:";

  int v0;

  cin>>v0;

  int v =v0;

  lowcost[v0] = 0;

  cout<<endl;

  Queue queue;

 

  for(i=1;i<n;i++)

  {

   edgeNode *p = adjlist[v0].link;

   while(p != NULL)

   {

    if(lowcost[v0] + p->cost<lowcost[p->no])

    {

     lowcost[p->no] = lowcost[v0] + p->cost;

     parent[p->no] = v0;

     heap_insert(priQue,num,p->no,lowcost[p->no]);

    }

    p = p->next;

   }

   queue = heap_extract_min(priQue,num);

   v0 = queue.no;

  }

  for(i=1;i<=n;i++)

  {

   mincost = 0;

   cout<<"從點"<<adjlist[v].info<<"開始到"<<adjlist[i].info<<"的最短路徑為:"<<endl;

   print_it(parent,adjlist,i);

   cout<<endl;

   cout<<"距離為:"<<lowcost[i]<<endl;

  }

 }

 system("pause");

 return 0;

}

 

--------------------------------------------------程序測試-----------------------------------------------------       

\

 

                 

請輸入案例的個數:1

請輸入節點數:5

請輸入邊數:10

請輸入節點1的名稱:a

請輸入節點2的名稱:b

請輸入節點3的名稱:c

請輸入節點4的名稱:d

請輸入節點5的名稱:e

請輸入邊1的起始節點與尾節點序號:1 2

此邊的權值:10

請輸入邊2的起始節點與尾節點序號:1 4

此邊的權值:5

請輸入邊3的起始節點與尾節點序號:2 3

此邊的權值:1

請輸入邊4的起始節點與尾節點序號:2 4

此邊的權值:2

請輸入邊5的起始節點與尾節點序號:3 5

此邊的權值:4

請輸入邊6的起始節點與尾節點序號:4 2

此邊的權值:3

請輸入邊7的起始節點與尾節點序號:4 3

此邊的權值:9

請輸入邊8的起始節點與尾節點序號:4 5

此邊的權值:2

請輸入邊9的起始節點與尾節點序號:5 1

此邊的權值:7

請輸入邊10的起始節點與尾節點序號:5 3

此邊的權值:6

從哪個節點開始:1

從點a開始到a的最短路徑為:

(1:a)

距離為:0

從點a開始到b的最短路徑為:

(1:a) (4:d) (2:b)

距離為:8

從點a開始到c的最短路徑為:

(1:a) (4:d) (2:b) (3:c)

距離為:9

從點a開始到d的最短路徑為:

(1:a) (4:d)

距離為:5

從點a開始到e的最短路徑為:

(1:a) (4:d) (5:e)

距離為:7

請按任意鍵繼續. .

 

作者 heyongluoyao8

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved