期末课程设计-交通咨询系统

#include<stdio.h>
#include<stdlib.h>
#include "string.h"
#define INF 32767
#define MAXV  10
typedef int InfoType;
typedef struct
{
    char cityname;
    int  no;          //顶点编号
    InfoType info;    //顶点其他信息
} VertexType;         //顶点类型
typedef struct
{
    int edges[MAXV][MAXV];  //邻接矩阵的边数组
    int n,e;                //顶点数,边数
    VertexType vxs[MAXV];   //存放顶点信息
} MGraph;                   //完整的图邻接矩阵类型

/************************ 功能1 *****************************/

//功能1 系统中的城市代号  中递归输出两城市最短路径中依次经过的城市
void Ppath(int path[],int i,int v)
{
    int k;
    k=path[i];
    if(k==v) return;   //两点重合 递归出口
    Ppath(path,k,v);   //递归输出k——v的最短路径
    printf("%d,",k);    //输出经过的城市k
}

//实现功能1 求两城市间的最短路径
void Dispath(int dist[],int path[],int s[],int n,int v)
{
    int i;
    for(i=0; i<n; i++)
    {
        if(s[i]==1&&dist[i]!=INF)
        {
            printf("从%d到%d的最短路径长度为:%d\t路径为:",v,i,dist[i]);
            printf("%d,",v);
            Ppath(path,i,v);   //调用函数输出v——i之间的最短路径
            printf("%d\n",i);
        }
        else printf("从%d到%d不存在路径\n",v,i);
    }
}

//参考 李春葆老师的《数据结构教程》 p233 狄克斯特拉算法 求最短路径
void Dijkstra(MGraph g,int v)
{
    int dist[MAXV],path[MAXV];
    int s[MAXV];
    int mindis,i,j,u;
    for(i=0; i<g.n; i++)
    {
        dist[i]=g.edges[v][i];  //距离初始化
        s[i]=0;                 //将s[]置空
        if(g.edges[v][i]<INF)   //路径初始化
            path[i]=v;          //顶点v到顶点i有边时,置顶点i的前一个顶点为v
        else
            path[i]=-1;         //顶点v到顶点i有边时,置顶点i的前一个顶点为-1
    }
    s[v]=1;
    path[v]=0;                  //源点编号v放在s中
    for(i=0; i<g.n; i++)        //循环直到所有定点的路径都求出
    {
        mindis=INF;             //mindis置最小长度初值
        for(j=0; j<g.n; j++)    //选取不在s中且具有最小距离的顶点u
            if(s[j]==0&&dist[j]<mindis)
            {
                u=j;
                mindis=dist[j];
            }
        s[u]=1;                 //顶点u加入s中
        for(j=0; j<g.n; j++)    //修改不在s中的顶点的距离
            if(s[j]==0)
                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;
                }
    }
    Dispath(dist,path,s,g.n,v); //输出最短路径
}

/*********************** 功能2 **************************/

//功能2 指定两点路径 中递归输出依次经过的城市
void Ppath2(int path[][MAXV],int i,int j)
{
    int k;
    k=path[i][j];        //ij之间是否有通路
    if(k==-1)return;     //没有通路,递归出口
    Ppath2(path,i,k);    //递归输出i——k 的最短路径
    printf("%d,",k);     //有通路,输出经过的城市k
    Ppath2(path,k,j);    // 递归输出k——j的最短路径
}

//  功能2 求最短路径 并输出
void Dispath2(int A[][MAXV],int path[][MAXV],int n)
{
    int i,j;
    printf("请输入起点和终点(i,j):");
    scanf("%d,%d",&i,&j);

    if(A[i][j]==INF)
    {
        if(i!=j)
            printf("从%d到%d没有路径\n",i,j);
    }
    else
    {
        printf("从%d到%d路径为:",i,j);
        printf("%d,",i);
        Ppath2(path,i,j);  //调用函数输出i与j之间的最短路径
        printf("%d",j);
        printf("\t路径长度为:%d\n",A[i][j]);
    }
}

//参考《数据结构教程》p239 弗洛伊德算法
void Floyd(MGraph g)
{
    int path[MAXV][MAXV],A[MAXV][MAXV];
    int i,j,k;
    for(i=0; i<g.n; i++)
        for(j=0; j<g.n; j++)
        {
            A[i][j]=g.edges[i][j];
            path[i][j]=-1;
        }
    for(k=0; k<g.n; k++)
    {
        for(i=0; i<g.n; i++)
            for(j=0; j<g.n; j++)
                if(A[i][j]>A[i][k]+A[k][j])
                {
                    A[i][j]=A[i][k]+A[k][j];
                    path[i][j]=k;             //修改最短路径
                }
    }
    Dispath2(A,path,g.n);                     //输出最短路径
}

void user_pr()
{
    printf("****************************************************************************\n");
    printf(" *       * *    ******          交通咨询系统          ******    * *       *\n");
    printf("  *     *   *   ****** 1-一个城市到所有城市的最短路径 ******   *   *     *\n");
    printf("   *   *     *  ****** 2-任意的两个城市之间的最短路径 ******  *     *   *\n");
    printf("    * *       * ****** 0-退出                         ****** *       * *\n");
    printf("     ******************************************************************\n");
    printf("\n");
    printf("请选择:");
}
int main()
{
    printf("对应城市代码\n    0——青岛,1——烟台,2——聊城,3——潍坊,4——济南,5——枣庄\n\n");
    int i,j,z,x;
    MGraph g;      //定义一个邻接矩阵
    int A[][MAXV]= {{INF,20,INF,15,INF,25},{20,INF,INF,21,INF,INF},
        {INF,INF,INF,INF,10,20},{15,21,INF,INF,16,26},{INF,INF,10,16,INF,20},
        {25,INF,20,26,20,INF}
    };
    g.n=6;
    g.e=10;
    for(i=0; i<g.n; i++)
        for(j=0; j<g.n; j++)
            g.edges[i][j]=A[i][j];  //对邻接矩阵赋值
    user_pr();
    scanf("%d",&z);
    while(z!=0)
    {
        switch(z)
        {
        case 1:
            printf("请输入城市代号:");
            scanf("%d",&x);
            switch(x)
            {
            case 0:
                printf("以下是最短路径:\n");
                Dijkstra(g,x);
                break;
            case 1:
                printf("以下是最短路径:\n");
                Dijkstra(g,x);
                break;
            case  2:
                printf("以下是最短路径:\n");
                Dijkstra(g,x);
                break;
            case  3:
                printf("以下是最短路径:\n");
                Dijkstra(g,x);
                break;
            case  4:
                printf("以下是最短路径:\n");
                Dijkstra(g,x);
                break;
            case 5:
                printf("以下是最短路径:\n");
                Dijkstra(g,x);
                break;
            default :
                printf("输入有误,请重新输入\n");
                printf("\n");
                user_pr();
            }
            printf("\n");
            user_pr();
            scanf("%d",&z);
            break;
        case 2:
            Floyd(g);
            printf("请选择:");
            printf("\n");
            user_pr();
            scanf("%d",&z);
            break;
        case 0:
            exit(-1);
            break;
        default:
            printf("输入有误,请重新输入\n");
            printf("\n");
            user_pr();
        }
    }
}

/****************************************************

  城市代号
  0——青岛,1——烟台,2——聊城,3——潍坊,4——济南,5——枣庄

  默认路径

    0   1   2   3   4   5
 0 INF  20 INF 15  INF 25
 1 20  INF INF 21  INF INF
 2 INF INF INF INF 10  20
 3 15  21  INF INF 16  26
 4 INF INF 10  16  INF 20
 5 25  INF 20  26  20  INF

****************************************************/








  • 24
    点赞
  • 117
    收藏
    觉得还不错? 一键收藏
  • 9
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值