数据结构与算法实验9-图的应用(最短路径)

一、实验目的

1.掌握图的基本存储方法。

2.掌握有关图的操作算法并用高级语言编程实现;

3.熟练掌握图的两种搜索路径的遍历方法。

二、实验软硬件要求

1、VC++ 6.0

三、实验预习

最短路径等相关算法。

四、实验内容(实验步骤、测试数据等)

1.问题描述:

编制一个可以对图进行遍历和用迪杰斯特拉算法求指定顶点到其余各顶点的最短路径的程序。

2.算法描述

1)记S为已经找到的从V0出发的最短路径的终点的集合,它的初始状态为空集。那

么,从V出发到图上其余各顶点VI可能达到的最短路径的初始值为

 D[i]=arcs[Locate Vex(G,V)][i].

2)选择Vj使得:

D[j]=Min{D[i] | vi不属于S} Vj就是当前求得的一条从V出发的最短路径的终点。

将j加入到S中。

3)修改从V出发到集合V—S上任意顶点Vk可达到的最短路径长度。如果:

D[j]+arcs[j][k]<D[k],则修改D[k]为D[k]=D[j]+arcs[j][k];

4)重复操作(2)(3)N-1次。由此求得从V到图上其余各顶点的最短路径是以路径长度递增的序列。

3.测试数据

4.实验结果要求。

1)求出vo到其余各点的最短距离。

2)打印出vo到其余各点的最短路径。

运行结果:

    实验体会

 (可以记录C语言中薄弱的部分,便于课后复习巩固,每次实验体会需要写两行。)

图的理解不够深刻,对图的代码应用比较薄弱,图的最短路径是指在特定两点之间找出一条权值最小的路径。注意点:存放各节点信息和选择最短路径的代码比较复杂,原理与栈的模式匹配相似。

六、源代码或重要代码

#include<stdio.h>

#include<malloc.h>

typedef int InfoType;

#define MAXV 100   //最大顶点个数

#define INF 32767  //INF表示无穷大

typedef struct

{

       int no;//顶点编号

       InfoType info;//顶点其他信息

}VertexType;//顶点类型

typedef struct

{//图的定义

       int edges[MAXV][MAXV]; //邻接矩阵

       int n;//顶点数

       int e;//边数

       VertexType vex[MAXV];//存放顶点信息

}MGraph;//图的邻接矩阵类型

void DisMat1(MGraph g);

void ppath(int path[],int i,int v);

void DisPath(int dist[],int path[],int s[],int n,int v);

void Dijkstra(MGraph g, int v);

void DisMat1(MGraph g)

{

       int i,j;

       for(i=0;i<g.n;i++)

       {

              for(j=0;j<g.n;j++)

                     if(g.edges[i][j]==INF)

                            printf("%4s","∞");

                     else

                            printf("%4d",g.edges[i][j]);

              printf("\n");

       }

}

void ppath(int path[],int i,int v)

{

       int k;

       k=path[i];

       if(k==v)return;

       ppath(path,k,v);

       printf("%d,",k);

}

void DisPath(int dist[],int path[],int s[],int n,int v)

{

       int i;

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

              if(s[i]==1)

              {

                     if(i!=v)

                     {

                            printf("  从%d到%d的最短路径长度为:%d\t路径:",v,i,dist[i]);

                            printf("%d,",v);ppath(path,i,v);printf("%d\n",i);

                     }

              }

              else printf("  从%d到%d不存在路径\n",v,i);

}

void Dijkstra(MGraph g, int v)

{

       int dist[MAXV],path[MAXV];

       int s[MAXV];

       int mindis,i,j,u,n=g.n;

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

       {

              dist[i]=g.edges[v][i];//距离初始化

              s[i]=0;//s[]制空

              if(g.edges[v][i]<INF)//路径初始化

                     path[i]=v;

              else

                     path[i]=-1;

       }

       s[v]=1;path[v]=0;//源点编号v放入s中

       for(i=0;i<n;i++)//循环直到所有顶点的最短路径都求出

       {

              mindis=INF;

              u=-1;

              for(j=0;j<n;j++)

                     if(s[j]==0&&dist[j]<mindis&&dist[j]!=0)//选取不在s中且具有最小距离的顶点u

                     {

                            u=j;

                            mindis=dist[j];

                     }

              if(u!=-1)

              {

                     s[u]=1;//顶点u加入s中

                  for(j=0;j<n;j++)//修改不在s中的顶点的距离

                     if(s[j]==0)

                     {//通过u到j的距离与v直接到j的距离比较

                            if(g.edges[u][j]<INF&&dist[u]+g.edges[u][j]<dist[j])

                            {

                                   dist[j]=dist[u]+g.edges[u][j];

                                   path[j]=u;

                            }

                     }

              }

             

       }

                     printf("输出最短路径:\n");

                     DisPath(dist,path,s,n,v);//输出最短路径

}

void main()

{

       int i,j,u=0;

       MGraph g;

       int A[MAXV][6]=

       {{0,INF,10,INF,30,100},

       {INF,0,5,INF,INF,INF},

       {INF,INF,0,50,INF,INF},

       {INF,INF,INF,0,INF,10},

       {INF,INF,INF,20,0,60},

       {INF,INF,INF,INF,INF,0}};

       g.n=6;g.e=8;

       for(i=0;i<g.n;i++)

              for(j=0;j<g.n;j++)

                     g.edges[i][j]=A[i][j];

       printf("有向图G的邻接矩阵:\n");

       DisMat1(g);

       Dijkstra(g,u);

       printf("\n");

}

  • 7
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值