数据结构算法实验8图的最短路径问题附源代码.docx
《数据结构算法实验8图的最短路径问题附源代码.docx》由会员分享,可在线阅读,更多相关《数据结构算法实验8图的最短路径问题附源代码.docx(16页珍藏版)》请在冰点文库上搜索。
![数据结构算法实验8图的最短路径问题附源代码.docx](https://file1.bingdoc.com/fileroot1/2023-5/23/02ee5061-3f99-4e08-8107-538f6f78b54e/02ee5061-3f99-4e08-8107-538f6f78b54e1.gif)
数据结构算法实验8图的最短路径问题附源代码
浙江大学城市学院实验报告
课程名称 数据结构与算法
实验项目名称 实验八图的最短路径问题
实验成绩 指导老师(签名) 日期
一.实验目的和要求
1.掌握图的最短路径概念。
2.理解并能实现求最短路径的DijKstra算法(用邻接矩阵表示图)。
二.实验内容
1、编写用邻接矩阵表示有向带权图时图的基本操作的实现函数,基本操作包括:
①初始化邻接矩阵表示的有向带权图 voidInitMatrix(adjmatrixG);
②建立邻接矩阵表示的有向带权图voidCreateMatrix(adjmatrixG,intn)(即通过输入图的每条边建立图的邻接矩阵);
③输出邻接矩阵表示的有向带权图voidPrintMatrix(adjmatrixG,intn)(即输出图的每条边)。
把邻接矩阵的结构定义以及这些基本操作函数存放在头文件Graph2.h中。
2、编写求最短路径的DijKstra算法函数voidDijkstra(adjmatrix GA, int dist[], edgenode *path[],int i,int n),该算法求从顶点i到其余顶点的最短路径与最短路径长度,并分别存于数组path和dist 中。
编写打印输出从源点到每个顶点的最短路径及长度的函数void PrintPath(intdist[], edgenode*path[],int n)。
3、编写测试程序(即主函数),首先建立并输出有向带权图,然后计算并输出从某顶点v0到其余各顶点的最短路径。
要求:
把指针数组的基类型结构定义edgenode、求最短路径的DijKstra算法函数、打印输出最短路径及长度的函数PrintPath以及主函数存放在文件test9_2.cpp中。
测试数据如下:
4、填写实验报告,实验报告文件取名为report8.doc。
5、上传实验报告文件report8.doc与源程序文件test9_2.cpp及Graph2.h到Ftp服务器上自己的文件夹下。
三.函数的功能说明及算法思路
包括每个函数的功能说明,及一些重要函数的算法实现思路
【结构说明】
constint MaxVertexNum=10;//图的最大顶点数
constint MaxEdgeNum=100;//边数的最大值
constintMaxValue=32767;//权值的无穷大表示
typedef intadjmatrix[MaxVertexNum][MaxVertexNum]; //邻接矩阵
typedefstruct Node{
intadjvex;
structNode *next;
}edgenode;//路径结点
【函数说明】
① void InitMatrix(adjmatrix&G)
功能:
初始化邻接矩阵表示的有向带权图
思路:
将邻接矩阵中的所有权值设置为无穷大(MaxValue)
②voidCreateMatrix(adjmatrix &G, intn)
功能:
建立邻接矩阵表示的有向带权图(即通过输入图的每条边建立图的邻接矩阵)
思路:
按照输入的顶点信息和权值信息,更新邻接矩阵内对应的值
③voidPrintMatrix(adjmatrix G,intn)
功能:
输出邻接矩阵表示的有向带权图(即输出图的每条边)
思路:
按照一定的格式输出邻接矩阵
④voidDijkstra(adjmatrixGA, intdist[], edgenode*path[],int i, int n)
功能:
求最短路径的DijKstra算法函数
思路:
按照从源点到其余每一顶点的最短路径长度递增的次序依次求出从源点到每个顶点的最短路径及长度。
设立一个集合S,用以保存已求得最短路径的终点,其初值为只有一个元素,即源点;一个数组dist[n],其每个分量dist[j]保存从源点经过S集合中顶点最后到达顶点 j的路径中最短路径的长度,其初值为从源点到每个终点的弧的权值(没弧则置为∞);一个指针数组path[n],path[j]指向一个单链表,保存相应于dist[j]的从源点到顶点j 的最短路径(即顶点序列),初值为空。
⑤ voidPATH(edgenode*path[],inti, intj)
功能:
将path[i]的路径改为path[j]的路径+i
思路:
分为三个步骤:
一,删除path[i]中原来保存的链表;二,将path[j]的路径复制给path[i];三,将j结点加入path[i]的路径中
⑥void PrintPath(int dist[], edgenode*path[], int n){
功能:
打印输出从源点到每个顶点的最短路径及长度的函数
思路:
按照一定的格式遍历输出从源点到每个顶点的最短路径及长度
四.实验结果与分析
包括运行结果截图等
ﻩ【测试数据】
顶点数:
7
输入弧的信息:
尾顶点
头顶点
权值
0
1
8
0
3
5
1
2
2
1
4
10
2
4
6
2
5
5
3
1
3
3
5
7
3
6
15
6
5
9
正确的邻接矩阵应为:
∞
8
∞
4
∞
∞
∞
∞
∞
2
∞
10
∞
∞
∞
∞
∞
∞
6
5
∞
∞
3
∞
∞
∞
7
15
∞
∞
∞
∞
∞
∞
∞
∞
∞
∞
∞
9
∞
∞
∞
∞
∞
∞
∞
∞
∞
下面以测试数据为基准,给出DijKstra算法生成最短路径的状态变化图:
(※注:
顶点旁边的
【状态①】 【状态②】
【状态③】 【状态④】
【状态⑤】 【状态⑥】
【状态⑦(最短路径)】
五.心得体会
记录实验感受、上机过程中遇到的困难及解决办法、遗留的问题、意见和建议等。
【附录----源程序】
[Test9_2.cpp]
#include
#include<stdlib.h>
#include<iostream.h>
#include<string.h>
#include"Graph2.h"
typedefstructNode{
int adjvex;
struct Node *next;
}edgenode;
void main(){
ﻩintn;
adjmatrix G;
edgenode*path[MaxVertexNum];
ﻩintdist[MaxVertexNum];
ﻩvoidDijkstra( adjmatrixGA,intdist[], edgenode *path[],inti, intn);
voidPrintPath(int dist[],edgenode*path[],intn);
ﻩInitMatrix(G);
ﻩprintf("输入要构造的图顶点数\n");
scanf("%d",&n);
CreateMatrix(G,n);
PrintMatrix(G,n); //打印图的邻接矩阵
ﻩcout<<endl<<endl<<"**************以下为DijKstra算法部分**************"<ﻩDijkstra(G, dist,path,0,n);
PrintPath(dist,path,n);
}
//求最短路径的DijKstra算法函数
void Dijkstra(adjmatrixGA, intdist[], edgenode*path[], inti,intn){
ﻩintj,k;
ﻩint v= 1,minIndex;
ﻩvoidPATH(edgenode *path[], int i, int j);
bool*isStepped;
ﻩ//初始化部分
ﻩ//isStepped:
申请n个空间,除i以外均为false
//dist:
邻接矩阵中i顶点到各顶点的距离
ﻩ//path:
邻接矩阵中i顶点到各顶点若有路径,则保存;无路径置为NULL
ﻩisStepped=newbool[n];
for(j =0; j ﻩdist[j]=GA[i][j];
if(dist[j] !
=MaxValue&& j!
=i){
path[j]=newedgenode;
ﻩpath[j]->adjvex =i;
ﻩpath[j]->next= newedgenode;
ﻩﻩpath[j]->next->adjvex =j;
ﻩﻩpath[j]->next->next=NULL;
ﻩ}
elsepath[j]=NULL;
ﻩisStepped[j]=false;
ﻩ}
isStepped[i]=true;
while(v<=n){
ﻩ//尝试查找当前最小路径结点,用minIndex保存顶点
ﻩminIndex=i;
for (k=0; k<n;k++){
ﻩif(dist[k] isStepped[k]))
ﻩﻩﻩminIndex= k;
ﻩ}
ﻩﻩ//有查找到最小路径顶点,则将其并入集合
if(minIndex!
=i)
ﻩisStepped[minIndex]=true;
ﻩﻩ//未查找到,则说明路径都为∞,退出
ﻩﻩelse
ﻩbreak;
//通过while中确定的最小路径顶点(minIndex)到达当前顶点
ﻩ//若路径长度小于dist中保存的路径长度,则修改
ﻩﻩfor(k = 0;k< n; k++){
ﻩﻩif(GA[minIndex][k]+dist[minIndex]< dist[k]){
ﻩﻩdist[k]= GA[minIndex][k]+dist[minIndex];
ﻩﻩﻩﻩPATH(path,k,minIndex);
}
ﻩ}
ﻩﻩv++;
}
}
//将path[i]的路径改为path[j]的路径+i
voidPATH(edgenode*path[],int i, intj){
ﻩedgenode*p,*q,*t;
ﻩ//删除path[i]中原来保存的链表
ﻩwhile(path[i]!
= NULL){
ﻩﻩp=path[i]->next;
ﻩﻩdelete path[i];
ﻩpath[i]= p;
}
ﻩ//将path[j]的路径复制给path[i]
p =newedgenode;
p->adjvex = path[j]->adjvex;
ﻩpath[i]=p;
t=path[j]->next;
while(t!
=NULL){
ﻩﻩq= p;
ﻩp = new edgenode;
ﻩp->adjvex=t->adjvex;
q->next=p;
ﻩt= t->next;
ﻩ}
//将j结点加入path[i]的路径中
q=p;
p=new edgenode;
ﻩp->adjvex=i;
ﻩp->next=NULL;
q->next=p;
}
//打印输出从源点到每个顶点的最短路径及长度的函数
void PrintPath(int dist[],edgenode *path[],int n){
inti;
edgenode*p;
ﻩfor (i =1; i ﻩcout<<"[v0->v"<
cout<<"最短路径:
";
ﻩﻩp=path[i];
ﻩif (p==NULL){
ﻩﻩcout<<"无路径!
"<ﻩcontinue;
ﻩ}
while(p!
=NULL){
ﻩﻩcout<<"v"<adjvex<<"";
p= p->next;
}
ﻩcout<"<<dist[i]<<endl<<endl;ﻩﻩ
ﻩ}
}
[Graph2.h]
const int MaxVertexNum=10;//图的最大顶点数
constintMaxEdgeNum=100; //边数的最大值
constintMaxValue=32767;//权值的无穷大表示
typedefint adjmatrix[MaxVertexNum][MaxVertexNum];//邻接矩阵
//①初始化邻接矩阵表示的有向带权图
void InitMatrix(adjmatrix&G)
{
ﻩint i,j;
for(i=0;i<MaxVertexNum;i++) //邻接矩阵初始化
for(j=0;j<MaxVertexNum;j++)
G[i][j]=MaxValue;
}
//②建立邻接矩阵表示的有向带权图(即通过输入图的每条边建立图的邻接矩阵)
voidCreateMatrix(adjmatrix &G,intn)
{
intv, w, q;
ﻩprintf("按照:
尾顶点名->头顶点名,权值输入数据,以0->0,0结尾:
如A->B,23 \n");
while(true){ //构造邻接矩阵
scanf("%d->%d,%d",&v,&w,&q);//输入弧的两个定点及该弧的权重
ﻩﻩgetchar();
ﻩﻩif(v== 0&&w==0)break;
if(v <0||v>= n ||w <0||w>= n){cerr<<"vertexERROR!
";exit
(1);}
G[v][w]=q;
}
}
//③输出邻接矩阵表示的有向带权图(即输出图的每条边)
voidPrintMatrix(adjmatrixG,intn)
{
int i,j;
ﻩcout<ﻩcout<<"Your Graphis:
"<<endl<<endl;
for(i=0;i for(j=0;j<n;j++){
ﻩif(G[i][j]!
=MaxValue)printf("%2d |",G[i][j]);
ﻩﻩelseprintf("∞|");
}
ﻩprintf("\n");
ﻩ}
}