数据结构课程设计

来源:互联网 发布:mac book air能用几年 编辑:程序博客网 时间:2024/05/14 19:27


 

 

 

 

 

《数据结构》课程设计

 

 

 

 

 

 

 

 

学生姓名

谢佳娜

所在专业

信息管理与信息系统

所在班级

1132

学号

201311671225

任课老师

     易学明

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  

 

    

一、概述 ............................................................................. 1 

二、系统分析 .........................................................................1

三、概要设计 ..................................................................... 2 

四、详细设计 ..................................................................... 3

 4.1建立图的存储结构 ................................................... 3

 4.2单源最短路径 ........................................................... 4 

 4.3任意一对顶点之间的最短路径 ............................... 4 

五、心得体会 ................................................................. 5 

六、参考文献 ........................................................................5 

七、附录 .................................................................................. 8

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 一、概述     

   GDOU真是一个好地方,校园如一座大花园,美丽而宽广。校园有很多建筑如教学楼、饭堂、宿舍楼、图书馆、体育馆、运动场、商业街、医院等,还有一些著名的风景点。现根据学校的平面图,找出一些重要的场所,画出学校的平面图(场所可以根据其重要性适当减少),根据实际画出不同点间的路径,并估算每两个场所间的路径长。 

二、系统分析 

设计一个系统,能查询从学校任意一点到另一点之间的最短路径对于不同的咨询要求,可输入两点间的路程、所需时间或是所需费用等信息。 

针对最短路径问题,在本系统中采用图的相关知识,以解决在实际情况中的最短路径问题,本系统中包括了建立图的存储结构、单源最短问题、对任意一对顶点间最短路径问题三个问题,这对以上几个问题采用了迪杰斯特拉算法和弗洛伊德算法。

三、概要设计 

可以将该系统大致分为三个部分:    

 建立交通网络图的存储结构; 

 解决单源最短路径问题; 

 实现两个点之间的最短路径问题。

  1. 详细设计 

     4.1建立图的存储结构 

    定义交通图的存储结构。邻接矩阵是表示图形中顶点之间相邻关系的矩阵。设G=(V,E)是具有n个顶点的图,则G的邻接矩阵是具有如下定义的n阶方阵。其他情况或或,若0E(G)V,V)V,(V],[jijiijWjiA 注:一个图的邻接矩阵表示是唯一的!其表示需要用一个二维数组存储顶点之间相邻关系的邻接矩阵并且还需要用一个具有n个元素的一维数组来存储顶点信息(下标为i的元素存储顶点iV的信息)。 邻接矩阵的存储结构: 

    #define MVNum 100 //最大顶点数 typedef struct { 

         VertexType vexs[MVNum];//顶点数组,类型假定为char      Adjmatrix  arcs[MVNum][MVNum];//邻接矩阵,假定为int }MGraph; 

    注:由于有向图的邻接矩阵是不对称的,故程序运行时只需要输入所有有向边及其权值即可。 

    4.2单源最短路径 

    单源最短路径问题:已知有向图(带权),期望找出从某个源点SVG中其余各顶点的最短路径。 

    迪杰斯特拉算法即按路径长度递增产生诸顶点的最短路径算法。 算法思想:设有向图G=(V,E),其中V={1,2,……n}cost是表示G的邻接矩阵, 

        cost[i][j]表示有向边<i,j>的权。若不存在有向边<i,j>,则cost[i][j] 的权为无穷大(这里取值为32767)。设S是一个集合,集合中一个元素表示一个顶点,从源点到这些顶点的最短距离已经求出。设顶点V1为源点,集合S的初态只包含顶点V1。数组dist记录从源点到其它各顶点当前的最短距离,其初值为dist[i]= cost[i][j]i=2,……n。从S之外的顶点集合V-S中选出一个顶点w,使dist[w] 的值最小。于是从源点到达w只通过S中的顶点,把w加入集合S中,调整dist中记录的从源点到V-S中每个顶点v的距离:从原来的dist[v]dist[w]+cost[w][v]中选择较小的值作为新的dist[v]。重复上述过程,直到S中包含V中其余顶点的最短路径。 

        最终结果是:S记录了从源点到该顶点存在最短路径的顶点集合,数组dist记录了从源点到V中其余各顶点之间的最短路径,path是最短路径的路径数组,其中path[i]表示从源点到顶点i之间的最短路径的前驱顶点。 

    4.3任意一对顶点之间的最短路径 

        任意顶点对之间的最短路径问题,是对于给定的有向网络图

    G=(V,E),要对G中任意一对顶点有序对,“V,W(VW)”,找出VW的最短路径。而要解决这个问题,可以依次把有向网络图中每个顶点作为源点,重复执行前面的迪杰斯特拉算法n次,即可求得每对之间的最短路径。 

        费洛伊德算法的基本思想:假设求从ViVj的最短路径。如果存在一条长度为arcs[i][j]的路径,该路径不一定是最短路径,还需要进行n次试探。首先考虑路径<vi,v1><v1,vj>是否存在。如果存在,则比较路径<vi.vj><vi,v1,vj>的路径长度,取长度较短者为当前所求得。该路径是中间顶点序号不大于1的最短路径。其次,考虑从vivj是否包含有顶点v2为中间顶点的路径< vi,,v2,,vj>,若没有,则说明从vivj的当前最短路径就是前一步求出的;若有,那么<vi,,v2,,vj>可分解为<vi,,v2><v2,,vj>,而这两条路径是前一次找到的中间点序号不大于1的最短路径,将这两条路径长度相加就得到路径<vi,,v2,vj>的长度。将该长度与前一次中求得的从vivj的中间顶点序号不大于1的最短路径比较,取其长度较短者作为当前求得的从vivj的中间顶点序号不大于2的最短路径。依此类推……直至顶点vn加入当前从vivj的最短路径后,选出从vivj的中间顶点序号不大于n的最短路径为止。由于图G中顶点序号不大于n,所以vivj的中间顶点序号不大于n的最短路径,已考虑了所有顶点作为中间顶点的可能性,因此,它就是vivj的最短路径。 

     

    五、心得体会

    在整个程序设计过程中,又让我更深入的理解了Dijkstra算法的精髓含义,此算法共用过三次,切实体会到了其广泛的用途,无论是现实中道路的最短路径,还是在计算机网络中的链路的时延或费用,都可以来解决最短路径的问题。

    另外,在设计过程中,难免遇到些问题,自己思考或者参考网络资源的学习中都让思维和程序设计有了进一步的提高。

     

  1. 参考文献

    数据结构(C++版)学习辅导与实验指导(第2版)

    七、附录 

     

    #include<stdio.h> 

    #include<stdlib.h> 

    #define MVNum 100 

    #define Maxint 32767 

    enum boolean{FALSE,TRUE}; 

    typedef char VertexType;

     typedef int Adjmatrix; 

    typedef struct

    {  VertexType vexs[MVNum]; 

     Adjmatrix arcs[MVNum][MVNum]; 

    }MGraph; 

    int D1[MVNum],p1[MVNum]; 

    int D[MVNum][MVNum],p[MVNum][MVNum];

     void CreateMGraph(MGraph * G,int n,int e) 

    {  

    int i,j,k,w; 

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

     G->vexs[i]=(char)i; 

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

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

      G->arcs[i][j]=Maxint; 

      printf("输入%d条边的i.jw:\n",e);  

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

    {   

     scanf("%d,%d,%d",&i,&j,&w);  

      G->arcs[i][j]=w; 

      }   

    printf("有向图的存储结构建立完毕!\n");

     } 

    void Dijkstra(MGraph *G,int v1,int n) 

    {  

    int D2[MVNum],p2[MVNum];

      int v,i,w,min; 

     enum boolean S[MVNum]; 

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

      S[v]=FALSE;  

         D2[v]=G->arcs[v1][v];  

      if(D2[v]<Maxint)  

      p2[v]=v1; 

     else 

       p2[v]=0; 

     } 

     D2[v1]=0; 

    S[v1]=TRUE; 

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

      min=Maxint; 

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

      if(!S[w] && D2[w]<min) 

       {v=w;min=D2[w];

    }   

     S[v]=TRUE;  

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

       if(!S[w] && (D2[v]+G->arcs[v][w]<D2[w]))

    {   

       D2[w]=D2[v]+G->arcs[v][w];  

    p2[w]=v;   

      }   

     } 

     printf("路径长度路径\n"); 

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

      printf("%5d",D2[i]); 

      printf("%5d",i);v=p2[i];  

     while(v!=0){ 

       printf("<-%d",v);  

      v=p2[v]; 

      }  

     printf("\n"); 

     } 

    void Floyd(MGraph *G,int n) 

     int i,j,k,v,w;  

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

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

      {  

      if(

     G->arcs[i][j]!=Maxint)    

     p[i][j]=j; 

       else    

     p[i][j]=0;   

     D[i][j]=G->arcs[i][j];  

     }  

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

     {  

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

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

     {    

      if(D[i][k]+D[k][j]<D[i][j]) 

     {

       D[i][j]=D[i][k]+D[k][j];  

         p[i][j]=p[i][k];     

     }    

     }  

     } 

    void main() 

     MGraph *G; 

     int m,n,e,v,w,k; 

     int xz=1; 

     G=(MGraph *)malloc(sizeof(MGraph)); 

     printf("输入图中顶点个数和边数n,e:"); 

     scanf("%d,%d",&n,&e); 

     CreateMGraph(G,n,e);  

     while(xz!=0)

    {

    printf("************求任意两点之间最短路径************\n"); 

       printf("=========================================\n");    printf("1.求一个点到另外所有点的最短路径\n"); 

       printf("2.求任意的两个点之间的最短路径\n"); 

       printf("=========================================\n"); 

       printf("请选择 :12,选择0退出:\n"); 

       scanf("%d",&xz);    

     if (xz==2)

    {    

     Floyd(G,n);   

      printf("输入源点(或起点)和终点:v,w:");  

       scanf("%d,%d",&v,&w);   

      k=p[v][w];    

     if (k==0)    

      printf("顶点%d%d无路径!\n",v,w);  

       else    

     {    

      printf("从顶点%d%d最短路径路径是:%d",v,w,v); 

         while (k!=w)

    {      

     printf("--%d",k);   

        k=p[k][w]; 

         }     

     printf("--%d",w);  

        printf("径路长度:%d\n",D[v][w]); 

        }   

     }    

    else      

         if(xz==1)    

      printf(“求单源路径,输入源点v :”); 

    }

    Scanf(“%d”,&v);Dijkstra(G,v,n);

    }

    Printf(“结束求最短路径\n”);

     

     

     

     

     

     

     

0 0