数据结构实验报告 最短路径.docx
《数据结构实验报告 最短路径.docx》由会员分享,可在线阅读,更多相关《数据结构实验报告 最短路径.docx(16页珍藏版)》请在冰豆网上搜索。
数据结构实验报告最短路径
实验报告
实验名称最短路径
课程名称数据结构与算法实验
|
|
专业班级:
信息安全
学号:
姓名:
实验六最短路径
一、实验目的
1.学习掌握图的存储结构
2.学会编写求最短路径的算法
二、实验内容
1、实验题目
编写代码实现Dijkstra生成最短路径的算法,其中要有完整的图的输入输出
2、简单介绍
图的存储:
用邻接矩阵,这样会方便不少。
邻接矩阵是一个二维数组,数组中的元素是边的权(一些数值),数组下标号为结点的标号。
(1)例如二维数组中的一个元素M[5][6]的值为39,则表示结点5、6连接,且其上的权值为39。
(2)用邻接矩阵存储图,对图的读写就简单了。
因为邻接矩阵就是一个二维数组,因此对图的读写就是对二维数组的操作。
只要能弄清楚边的编号,就能把图读入了。
用一对结点表示边(也就是输入的时候输入一对结点的编号)
求最短路径的算法:
求最短路径就是求图中的每一个点到图中某一个给定点(这里认为是编号为0的点)的最短距离。
具体算法就是初始有一个旧图,一个新图。
开始的时候旧图中有所有的结点,新图中初始为只有一个结点(源点,路径的源头)。
整个算法就是不停的从旧图中往新图中添加点,直到所有的点都添加到新图中为止。
要实现这个算法,除了用二维数组保存图,还需要使用到两个辅助的数组
数组find[N]:
此数组是用来表示标号对应的结点是否已经被添加到新图中(因为只有旧图中的点我们才需要添加到新图中,并且只有旧图中点到源点的距离,我们才需要进行更新)其中N为图中结点的个数。
数组distance[N]:
此数组记录图中的点到源点的距离。
这个数组里面存放的值是不断进行更新的。
其中N为图中结点的个数。
3、程序简单模板
只是参考,不需要照着这个来写
//最短路径
#ifndefMYGRAPH_H_
#defineMYGRAPH_H_
classMyGraph
{
public:
voidreadDirectedGraph();
MyGraph(intsize);//构造函数中设置图的大小,分配空间
voidwriteGraph();
voidshortPath(intsource);//求最短路径
protected:
private:
int**m_graph;//用二维数组保存图
intm_size;//图的大小
};
#endif
/////////////////////////////////////////////////////////////////////
//构造函数中设置图的大小,分配空间
MyGraph:
:
MyGraph(intsize)
{
inti,j;
m_size=size;
//给图分配空间
m_graph=newint*[m_size];
for(i=0;i{
m_graph[i]=newint[m_size];
}
for(i=0;i{
for(j=0;j{
m_graph[i][j]=INT_MAX;
}
}
}
三、实验代码
#include
#include
#include
#include
#include
usingnamespacestd;
structprimnode
{
public:
charbegvex;
charendvex;
intlowcost;
};
structadknode
{
intdist;//最近距离
charway[50];//顶点数组
intnodenum;//经过的顶点数
};
classMgraph//邻接矩阵储存结构
{
public:
Mgraph(){}
~Mgraph(){}
voidCreatMGraph();
voidDFS(int);//用递归实现
voidDFS1(int);//非递归
voidBFS(int);
voidprint();
voidprim();
intmini();
intlow();//最短距离函数的辅助函数
intLocateVex(char);
voidkruskal();
voidDijkstra();
voidFloyd();
private:
intnumber;//顶点数目
intarcnum;//边的数目
charvexs[50];
intarcs[50][50];
intvisited[50];//便利时的辅助工具
primnodecloseedge[50];//prim
adknodedist[50];//最短路径
intD[20][20];//floyd算法距离
intP[20][20][20];//floyd算法路径
};
intMgraph:
:
LocateVex(chars)
{
for(inti=0;iif(vexs[i]==s)
returni;
return-1;
}
voidMgraph:
:
print()
{
cout<<"顶点为:
";
for(intk=0;kcout<cout<for(inti=0;i{
for(intj=0;jcout<cout<}
for(intm=0;mcout<cout<}
voidMgraph:
:
CreatMGraph()//图的邻接矩阵储存结构
{
charvex1,vex2;
inti,j,k,m;
cout<<"请输入定点数,边数:
"<cin>>number>>arcnum;
cout<<"请输入顶点(字符串类型):
"<for(i=0;icin>>vexs[i];
for(i=0;ifor(j=0;jarcs[i][j]=1000;
for(k=0;k{
cout<<"请输入边的两个顶点及边的权值:
"<cin>>vex1>>vex2>>m;
i=LocateVex(vex1);
j=LocateVex(vex2);
arcs[i][j]=m;
arcs[j][i]=m;
}
}
voidMgraph:
:
DFS(inti=0)//用递归实现
{
intj;
cout<";
visited[i]=1;
for(j=0;j{
if(!
(arcs[i][j]==1000)&&!
visited[j])
DFS(j);
}
}
voidMgraph:
:
DFS1(inti=0)//非递归
{
stackst;
st.push(i);
while(!
st.empty())
{
intj=st.top();
st.pop();
cout<";
visited[j]=1;
for(intk=0;k{
if((!
(arcs[j][k]==1000))&&!
visited[k])
st.push(k);
}
}
}
voidMgraph:
:
BFS(inti=0)//广度优先遍历
{
dequede;
de.push_back(i);
cout<";
visited[i]=1;
while(!
de.empty())
{
intk=de.front();
for(intj=0;j{
if(arcs[k][j]!
=1000&&!
visited[j])
{
cout<";
visited[j]=1;
de.push_back(j);
}
}
de.pop_front();
}
}
intMgraph:
:
mini()
{
staticinti;
intmin=0;
for(intj=0;j{
if(!
visited[j])
{
if(closeedge[min].lowcost>closeedge[j].lowcost)
{
min=j;
}
}
}
i=min;
cout<<"包括边("<returni;
}
voidMgraph:
:
prim()
{
charu;
cout<<"请输入起始顶点:
"<cin>>u;
inti=LocateVex(u);
visited[i]=1;
for(intj=0;j{
closeedge[j].begvex=u;
closeedge[j].endvex=vexs[j];
closeedge[j].lowcost=arcs[i][j];
}
for(intm=1;m{
intn=mini();
visited[n]=1;
closeedge[n].lowcost=1000;
for(intp=0;p{
if(!
visited[p])
{
if(arcs[p][n]{
closeedge[p].lowcost=arcs[p][n];
closeedge[p].begvex=vexs[n];
}
}
}
}
}
voidMgraph:
:
kruskal()
{
inta,b,k=0;
intmin=1000;
intarcs1[20][20];
for(intm=0;mvisited[m]=m;//每一个顶点属于一颗树
for(inti=0;ifor(intj=0;jarcs1[i][j]=arcs[i][j];
while(k{
min=1000;
for(inti=0;i{
for(intj=0;j{
if(arcs1[i][j]{
a=i;
b=j;
min=arcs1[i][j];
}
}
}
if(visited[a]!
=visited[b])
{
cout<<"包括边("<k++;
for(intn=0;n{
if(visited[n]==visited[b])
visited[n]=visited[a];
}
}
else
arcs1[a][b]=arcs[b][a]=1000;
}
}
voidMgraph:
:
Dijkstra()
{
cout<<"请输入起始点"<charu;
cin>>u;
inti=LocateVex(u);
visited[i]=1;
for(intj=0;j{
dist[j].dist=arcs[i][j];
dist[j].nodenum=0;
}
for(j=1;j{
intdistance=1000;
intmin=0;
for(intn=0;n{
if(!
visited[n])
{
if(distance>dist[n].dist)
{
distance=dist[n].dist;
min=n;
}
}
}
intm=min;
visited[m]=1;
for(n=0;n{
if(!
visited[n])
{
if((dist[m].dist+arcs[m][n]){
dist[n].dist=dist[m].dist+arcs[m][n];
dist[n].nodenum=0;
for(intx=0;x{
dist[n].way[x]=dist[m].way[x];
dist[n].nodenum++;
}
dist[n].way[dist[n].nodenum++]=vexs[m];
}}}}
//输出功能
for(intn=0;n{
if(n!
=i)
{if(dist[n].dist<1000)
{
cout<"<cout<<"经过的顶点为:
"<";
for(intp=0;p{cout<";
}
cout<}
else
cout<}}}
voidMgraph:
:
Floyd()
{
inti,j,m,n;
for(i=0;ifor(j=0;jfor(m=0;mP[i][j][m]=0;
for(i=0;ifor(j=0;j{
D[i][j]=arcs[i][j];
if(D[i][j]<1000)
{
P[i][j][i]=1;
P[i][j][j]=1;
}}
for(i=0;ifor(j=0;jfor(m=0;m{
if(i==j||j==m||i==m)
continue;
if(D[i][m]+D[m][j]{
D[i][j]=D[i][m]+D[m][j];
for(n=0;n{
P[i][j][n]=P[i][m][n]||P[m][j][n];
}}}
for(i=0;ifor(j=0;j{
if(D[i][j]<1000)
{
cout<"<cout<<"经过的顶点为:
";
for(m=0;m{
if(P[i][j][m])
{
cout<";
}}
cout<else
if(i!
=j)
cout<}
}
intmain()
{
Mgraphg;
g.CreatMGraph();
g.Floyd();
return0;
}
四、实验结果
五、实验总结
本次实验主要是学习掌握图的存储结构,学会编写求最短路径的算法。
本次实验的算法虽有点复杂,但是多上机练习,完成本次实验也不是难事。