数据结构课设

来源:互联网 发布:情侣手环淘宝 互相感应 编辑:程序博客网 时间:2024/05/16 17:49

(1)问题描述

设计一个校园导游程序,为来访的客人提供各种信息查询服务。

(2)设计要求

  1. 设计中北大学的校园平面图。以图中顶点表示校内各景点,存放景点名称、代号、简介等信息;以边表示路径,存放路径长度等相关信息。
  2. 为来访客人提供图中任意景点相关信息的查询。
  3. 为来访客人提供图中任意景点的问路查询,即查询任意两相景点之间的一条最短的简单路径。
  4. 求校园图的关节点。
  5. 为来访客人提供图中任意景点问路查询,即求任意两个景点之间的所有路径。
  6. 为来访客人提供校园图中多个景点的最佳访问路线查询,即求途经这多个景点的最佳路径。


(3)代码

#include<stdio.h>#include<string.h>#include<stdlib.h>#define INF 0x3f3f3f3f//无穷大#define MAX 20//顶点最大值typedef struct//顶点类型{    char name[20];    int ID;    char info[500];} vertextype;typedef int edgetype;//边权值类型typedef struct{    vertextype vexs[MAX];    edgetype edges[MAX][MAX];//邻接矩阵图类型    int n, e;} graph;typedef int dist[MAX][MAX];   /* 距离向量类型*/typedef int path[MAX][MAX];   /* 路径类型*/graph g;void plan(){    printf("┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓\n");    printf("┃                                   ***中北大学校园平面图***                                 ┃\n");    printf("┃                                                                                            ┃\n");    printf("┃                                ╭─────╮    ╭─────╮                            ┃\n");    printf("┃                  ╔══════│中北医院⑴│══│文体中心⑵│═╗                        ┃\n");    printf("┃                  ║            ╰─────╯    ╰─────╯  ║                        ┃\n");    printf("┃                  ║                                              ║                        ┃\n");    printf("┃    ╭─────╮║    ╭────╮      ╭────╮        ╭───╮        ╭────╮┃\n");    printf("┃    │龙山公园⑶│╬══│科艺苑⑷│═══│图书馆⑸│════│主楼⑹│════│体育场⑺│┃\n");    printf("┃    ╰─────╯║    ╰────╯      ╰────╯        ╰───╯        ╰────╯┃\n");    printf("┃                  ║                                             ║                 ║      ┃\n");    printf("┃                  ║                                      ╭─────╮      ╭─────╮┃\n");    printf("┃                  ║                                      │行知广场⑻│      │科技园区⑼│┃\n");    printf("┃                  ║                                      ╰─────╯      ╰─────╯┃\n");    printf("┃                  ║                                                                ║      ┃\n");    printf("┃      ╭────╮║              ╭────╮      ╭───────╮              ║      ┃\n");    printf("┃      │柏林园⑽│╬═══════│足球场⑾│═══│学术交流中心⑿│═══════╝      ┃\n");    printf("┃      ╰────╯║              ╰────╯      ╰───────╯                      ┃\n");    printf("┃                  ║                                                                        ┃\n");    printf("┃             ╭────╮                                                                   ┃\n");    printf("┃             │德怀楼⒀│                                                                   ┃\n");    printf("┃             ╰────╯                                                                   ┃\n");    printf("┃                  ║                                                                        ┃\n");    printf("┃              ╭───╮                                                                    ┃\n");    printf("┃              │正门⒁│                                                                    ┃\n");    printf("┃              ╰───╯                                                                    ┃\n");    printf("┃                                                                                            ┃\n");    printf("┃                                   注:括号中数字代表景点序号                                ┃\n");    printf("┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛\n");}void mean(){    printf("\t\t\t\t┏━━━━━━━━━━━━━━━━━━━┓\n");    printf("\t\t\t\t┃             **请选择功能**           ┃\n");    printf("\t\t\t\t┃      1.查询景点信息                  ┃\n");    printf("\t\t\t\t┃      2.查询推荐路线                  ┃\n");    printf("\t\t\t\t┃      3.查询校园图关节点              ┃\n");    printf("\t\t\t\t┃      4.退出                          ┃\n");    printf("\t\t\t\t┗━━━━━━━━━━━━━━━━━━━┛\n");}void sub_mean(){    printf("\t\t\t\t┏━━━━━━━━━━━━━━━━━━━┓\n");    printf("\t\t\t\t┃             **请选择功能**           ┃\n");    printf("\t\t\t\t┃     1.查询两景点的最佳路径           ┃\n");    printf("\t\t\t\t┃     2.查询两景点之间所有路径         ┃\n");    printf("\t\t\t\t┃     3.查询途径多个景点的最佳访问路线 ┃\n");    printf("\t\t\t\t┃     4.退出                           ┃\n");    printf("\t\t\t\t┗━━━━━━━━━━━━━━━━━━━┛\n");    //*printf("请选择功能:");}/*函数功能:建立图的邻接矩阵存储结构*/void creat_graph(char *s, int c){    int i, j, k, w;    FILE *rf;    rf = fopen(s, "r");    if (rf)    {        fscanf(rf, "%d%d", &g.n, &g.e);        for (i = 1; i<=g.n; i++)        {            fscanf(rf, "%d%s ", &g.vexs[i].ID, g.vexs[i].name);            fgets(g.vexs[i].info, 500, rf);        }        for (i = 1; i<=g.n; i++)            for (j = 1; j<=g.n; j++)                if (i == j) g.edges[i][j] = 0;                else g.edges[i][j] = INF;        for (k = 0; k<g.e; k++)        {            fscanf(rf, "%d%d%d", &i, &j, &w);            g.edges[i][j] = w;            if (c == 0) g.edges[j][i] = w;   /*如果c==0则建立无向图邻接矩阵,否则建立有向图邻矩阵*/        }        fclose(rf);    }    else g.n = 0;}/*函数功能:Floyd方法求所有顶点对间的最短路径*/void floyd(path p, dist d){    int i, j, k;    for (i = 1; i<=g.n; i++)        for (j = 1; j<=g.n; j++)        {            d[i][j] = g.edges[i][j];            p[i][j]=j;        }    for (k = 1; k<=g.n; k++) /*递推求解每一对顶点间的最短距离*/    {        for (i = 1; i<=g.n; i++)            for (j = 1; j<=g.n; j++)                if (d[i][j]>(d[i][k] + d[k][j]))                {                    d[i][j] = d[i][k] + d[k][j];                    p[i][j] = p[i][k];                }    }}/*函数功能输出最短路径*/void put_short(int sta, int end,path p, dist d){    printf("\n最短距离为:\n");    printf("%dM", d[sta][end]);    printf("\n最佳路线为:\n");    int tmp=sta;    printf("(%d)%s",sta,g.vexs[sta].name);    while(tmp!=end)    {        tmp=p[tmp][end];        printf(" -> (%d)%s",tmp,g.vexs[tmp].name);    }    printf("\n");}int min(int a,int b){    return a>b?b:a;}/*函数功能:求割点的dfs过程*/void cut_dfs(int u,int *vis,int *dfn,int *par,int*low,int *cut){    int v;    static int dep=0;    int child=0;    vis[u]=1;    dfn[u]=low[u]=++dep;    for(v=1; v<=g.n; v++)    {        if(g.edges[u][v]!=INF&&g.edges[u][v])        {            if(!vis[v])            {                child++;                par[v]=u;                cut_dfs(v,vis,dfn,par,low,cut);                low[u]=min(low[u],low[v]);                if(par[u]==-1&&child>1)                {                    cut[u]=1;                }                else if(par[u]!=-1&&low[v]>=dfn[u])                {                    cut[u]=1;                }            }            else if(v!=par[u])            {                low[u]=min(low[u],dfn[v]);            }        }    }}/*函数功能:求割点*/void cutver(){    int vis[MAX],dfn[MAX],par[MAX],low[MAX],cut[MAX];    int i;    int flag=0;    for(i=1; i<=g.n; i++)    {        vis[i]=0;        par[i]=-1;        cut[i]=0;    }    for(i=1; i<=g.n; i++)    {        if(!vis[i])        {            cut_dfs(i,vis,dfn,par,low,cut);            break;        }    }    for(i=1; i<=g.n; i++)        if(cut[i])        {            flag=1;            break;        }    if(flag)    {        printf("校园图的关节点为:");        for(i=1; i<=g.n; i++)        {            if(cut[i])            {                flag=1;                printf(" (%d)%s",i,g.vexs[i].name);            }        }        printf("\n");    }    else    {        printf("对不起,该校园图没有关节点!\n");    }}/*函数功能:求两点间所有路径过程中求遍历过中的下一个点*/int find_first(int cur,int vis_ver[],int vis_edg[][MAX]){    int i;    for(i=1; i<=g.n; i++)        if(!vis_ver[i]&&!vis_edg[cur][i]&&g.edges[cur][i]!=INF&&i!=cur)            return i;    return -1;}/*函数功能:求两点间的所有路径*/void all_path(int sta,int end){    int i;    int vis_ver[MAX],vis_edg[MAX][MAX];    int stack[MAX],top=-1;    memset(vis_ver,0,sizeof(vis_ver));    memset(vis_edg,0,sizeof(vis_edg));    vis_ver[sta]=1;    stack[++top]=sta;    while(top>=0)    {        int em=stack[top];        if(em==end)        {            for(i=0; i<top; i++)                printf("(%d)%s -> ",stack[i],g.vexs[stack[i]].name);            printf("(%d)%s\n",stack[top],g.vexs[stack[top]].name);            printf("\n");            vis_ver[em]=0;            top--;        }        else        {            int cur=find_first(em,vis_ver,vis_edg);            if(cur>=0)            {                stack[++top]=cur;                vis_ver[cur]=1;                vis_edg[em][cur]=1;            }            else if(cur==-1)            {                vis_ver[em]=0;                for(i=1; i<=g.n; i++)                    vis_edg[em][i]=0;                top--;            }        }    }}/*函数功能:求途径多个点的最佳路径的辅助输出函数*/void shiftput(int sta, int end,path p, dist d){    int tmp=sta;    while(tmp!=end)    {        tmp=p[tmp][end];        printf(" -> (%d)%s",tmp,g.vexs[tmp].name);    }}/*函数功能:求途径多个点的最佳路径*/void road_path(int staver,int *path_ver,int vercou,path p,dist d){    int i,vis[MAX];    memset(vis,0,sizeof(vis));    for(i=0; i<vercou; i++)        vis[path_ver[i]]=2;//表示要经过的点    vis[staver]=1;    int cur=staver;    int flag=1;    printf("(%d)%s",staver,g.vexs[staver].name);    while(1)    {        flag=0;        int mindis=INF,minver=-1;        for(i=1; i<=g.n; i++)        {            if(vis[i]==2)            {                flag=1;                if(d[cur][i]<mindis)                {                    mindis=d[cur][i];                    minver=i;                }            }        }        if(flag==0) break;        shiftput(cur,minver,p,d);        vis[minver]=1;        cur=minver;    }    printf("\n");}int main(){    creat_graph("graph.txt", 0);    plan();    mean();    int cho,sub_cho;    while(scanf("%d",&cho))    {        getchar();        int i;        int staver, endver;        int vernum,vercou;        char yorn;        dist d;        path p;        int path_ver[MAX];        switch(cho)        {        case 1:            yorn='y';            while(1)            {                if(yorn=='n')                {                    system("cls");                    plan();                    mean();                    break;                }                else if(yorn=='y')                {                    system("cls");                    plan();                    printf("请输入景点序号:");                    scanf("%d", &vernum);                    getchar();                    puts(g.vexs[vernum].info);                }                else                {                    printf("输入错误!\n");                }                printf("是否继续查询景点信息?y/n ");                scanf("%c",&yorn);                getchar();            }            break;        case 2:            yorn='y';            while(1)            {                if(yorn=='n')                {                    out:system("cls");                    plan();                    mean();                    break;                }                else if(yorn=='y')                {                    system("cls");                    plan();                    sub_mean();                    scanf("%d",&sub_cho);                    getchar();                    switch(sub_cho)                    {                    case 1:                        floyd(p,d);                        yorn='y';                        while(1)                        {                            if(yorn=='n')                            {                                system("cls");                                plan();                                sub_mean();                                break;                            }                            else if(yorn=='y')                            {                                system("cls");                                plan();                                printf("请输入起点序号:");                                scanf("%d",&staver);                                getchar();                                printf("请输入终点序号:");                                scanf("%d",&endver);                                getchar();                                put_short(staver,endver,p,d);                            }                            else                            {                                printf("输入错误!");                            }                            printf("是否继续查询两点之间最短路径?y/n ");                            scanf("%c",&yorn);                            getchar();                        }                        break;                    case 2:                        yorn='y';                        while(1)                        {                            if(yorn=='n')                            {                                system("cls");                                plan();                                sub_mean();                                break;                            }                            else if(yorn=='y')                            {                                system("cls");                                plan();                                printf("请输入起点序号:");                                scanf("%d",&staver);                                getchar();                                printf("请输入终点序号:");                                scanf("%d",&endver);                                getchar();                                all_path(staver,endver);                            }                            else                            {                                printf("输入错误!");                            }                            printf("是否继续查询两点之间所有路径?y/n ");                            scanf("%c",&yorn);                            getchar();                        }                        break;                    case 3:                        floyd(p,d);                        yorn='y';                        while(1)                        {                            if(yorn=='n')                            {                                system("cls");                                plan();                                sub_mean();                                break;                            }                            else if(yorn=='y')                            {                                system("cls");                                plan();                                printf("请输入起点序号:");                                scanf("%d",&staver);                                getchar();                                printf("请输入要经过的景点数目:");                                scanf("%d",&vercou);                                getchar();                                printf("依次输入要经过的景点序号:\n");                                for(i=0; i<vercou; i++)                                {                                    scanf("%d",&path_ver[i]);                                    getchar();                                }                                road_path(staver,path_ver,vercou,p,d);                            }                            else                            {                                printf("输入错误!");                            }                            printf("是否继续查询途径多个景点的最佳路径?y/n ");                            scanf("%c",&yorn);                            getchar();                        }                        break;                    case 4:                        goto out;                        break;                    default:                        printf("输入错误!");                    }                }                printf("是否继续查询推荐路线?y/n ");                scanf("%c",&yorn);                getchar();            }            break;        case 3:            cutver();            printf("按任意键返回主菜单...");            getchar();            system("cls");            plan();            mean();            break;        case 4:            return 0;        default:            printf("输入错误!");        }    }    return 0;}


1 0
原创粉丝点击