校园景点导航图

 

兄弟我最近完成图中的的一个作业,纠结死我了。就是一个校园景点导航图,要求大家应该都懂,就是要用上DJS算法和Floyd算法

,整个书上估计就这两三个算法最难了。书,哥是看了一遍又一遍,都想吐了;别人的程序看了又看,还是不太明白。最后虽然完

成了这个作业,但还是不太满意。我是改了别人的算法过程写上去的,基本上就是按照原来的写的,它的意思我也只懂了一点点;

哎~下面就是我做的那个,有兴趣的可以拿下去运行一下,Dev C++可以运行,用Tc也应该可以运行的。

#define INFINITY 32700 /*无穷大*/
#define MAX_VERTEX_NUM 28     /*最大顶点数*/
#define MAX_EDGE_NUM   120    /* 最大边数*/
#define MAX 40
#include<stdlib.h>
#include<stdio.h>
#include<conio.h>
#include<string.h>

/*邻接矩阵表示图结构*/
typedef struct ArCell
{
   int adj;          /*路径长度 */

}ArCell,AdjMatrix[MAX_EDGE_NUM][MAX_EDGE_NUM];
typedef struct
{
    int code;                    /*顶点编号*/
    char name[30];        /*名称*/
    char introduction[100];        /*简介*/
}touristinfo;

typedef struct
{
    touristinfo vexs[MAX_VERTEX_NUM];        /*一维数组表示顶点信息*/
    AdjMatrix arcs;                                            /*二维数组表示弧的信息*/
    int vexnum,arcnum;                                    /*顶点数, 边数*/
}MGraph;
MGraph school;

void cmd(void );
void InitGraph(MGraph *G );
void Search(MGraph *G);/*fing a spot to look what have*/
void Menu(void );
void Browser(MGraph *G);
void ShortestPath_DJS(MGraph *G);    /*后面应该还有参数*/
void Floyd(MGraph * G);
int LocateVex(MGraph *G, char *v);

/*  如果要把输入的景点图存入文件,则可把这段注释去掉
void WriteToFile(MGraph *G);
void ReadFromFile(MGraph *G);   
void ReadFromFile(MGraph *G)
{
    FILE *rd;
    if((rd = fopen("D://校园景点图导航.dat", "r")) == NULL)
    {
       printf("文件打开失败!/n");      
       exit(1);
    }    
    if(fread(G, sizeof(MGraph), 1, rd))
    {
        printf("校园景点图导航初始化成功!...");            
    }
}
void WriteToFile(MGraph *G)
{
     FILE *wt;
     if((wt = fopen("D://校园景点图导航.dat", "w")) == NULL)
     {
         printf("文件打开失败!/n");      
         exit(1);     
     }
     if(fwrite(G, sieof(MGraph), 1, wt))
     {
        printf("校园景点图导航已成功存储!...");            
     }
}
*/
int main(void )
{
    system("color 1f");
    cmd();
    return 0;
}
void Browser(MGraph *G)
{
 int ivex;    
 printf("/n***景点编号*******景点名称**********景点简介********************/n");
 for(ivex = 0; ivex < G->vexnum; ivex++)
    printf("   %d             %s           %s/n", G->vexs[ivex].code, G->vexs[ivex].name, G->vexs[ivex].introduction);
 printf("*********************************************************************");
}

void cmd(void )
{
    int choice = 0;
    InitGraph(&school);
    while(1)
    {
        Menu();
        scanf("%d", &choice);
        getchar();
        switch(choice)
        {
            case 1:
                system("cls");
                Browser(&school);
                break;
            case 2:
                system("cls");
                ShortestPath_DJS(&school);
                break;
            case 3:
                system("cls");
                Floyd(&school);
                break;
            case 4:
                Search(&school);
                break;
            case 5:
                sleep(1);
                exit(1);
                break;
            default:
                break;
        }
    }
}
void Menu(void )
{
    printf("/n              欢迎咨询盐城师范学院导游图:/n");
    printf(" |*********************************************************|/n");

    printf(" |****************** 1.浏览校园全景.***********************|/n");

    printf(" |****************** 2.查看所有游览路线. ******************|/n");

    printf(" |****************** 3.选择出发点和目的地. ****************|/n");

    printf(" |****************** 4.查看景点信息. **********************|/n");

    printf(" |****************** 5.退出系统 .*************** ********* |/n");
    printf(" |*********************************************************|/n");
    printf("Option-:");
}

int LocateVex(MGraph *G, char *v)
{
    int c = -1, ivex = 0;
    for(ivex = 0; ivex < G->vexnum; ivex++)
    {
        if(strcmp(v, G->vexs[ivex].name) == 0)
        {
            c = ivex;
            break;
        }
    }
    return ivex;
}
/*         如果是想自己输入景点导航,则取消此注释
void CreateDN(MGraph *G)
{
    int ivex, jvex;
    int iarc;
    int weight = 0;
    char v1_name[30], v2_name[30];
    printf("请输入校园景点图的景点数和路径数: ");
    scanf("%d%d", &G->vexnum, &G->arcnum);
    getchar();
    for(ivex = 0; ivex < G->vexnum; ivex++)
    {
        printf("请输入第%d个景点的景点号: ", ivex + 1);
        scanf("%d", &G->vexs[ivex].code);
        getchar();
        printf("请输入第%d个景点的景点名:", ivex + 1);
        gets(G->vexs[ivex].name);
        printf("请输入第%d个景点的景点简介:", ivex + 1);
        gets(G->vexs[ivex].introduction);
    }
    for(ivex = 0; ivex < G->vexnum; ivex++)
        for(jvex = 0; jvex < G->vexnum; jvex++)
        {
            G->arcs[ivex][jvex].adj = INFINITY;
        }
   
    for(iarc = 0; iarc < G->arcnum; iarc++)
    {
        memset(v1_name, 0x00, sizeof(v1_name));
        memset(v2_name, 0x00, sizeof(v2_name));
        printf("请输入第%d条弧所依赖的第一个顶点:", iarc+1);
        gets(v1_name);
        printf("请输入第%d条弧所依赖的第二个顶点:", iarc+1);
        gets(v2_name);
        ivex = LocateVex(G, v1_name);
        jvex = LocateVex(G, v2_name);
        if(ivex >= 0 && jvex >= 0)
        {
            printf("请输入第%d条弧的权值:",iarc+1);
            scanf("%d", &weight);
            getchar();
        }
        else
        {
            printf("没有此景点丫!");
            iarc--;
        }
    }
}
*/
void InitGraph(MGraph *G)
{
    /*CreateDN(G);*/
   
    /*下面的在程序中已经初始化OK,若想采用其他方法初始化,注释即可*/
 int i,j;
 G->vexnum =28;                                   /*顶点个数*/
 G->arcnum =39;                                   /*边的个数*/
 for(i = 0; i < G->vexnum; i++)                        /*依次设置顶点编号*/
  G->vexs[i].code = i + 1;
 /*依次输入顶点信息*/
  strcpy(G->vexs[0].name ,"盐城师范学院大门");
  strcpy(G->vexs[0].introduction ,"离公交站近");
  strcpy(G->vexs[1].name ,"学校南正门");
  strcpy(G->vexs[1].introduction ,"与黄海学院接壤,育才路的入口");
  strcpy(G->vexs[2].name ,"成人教育学院");
  strcpy(G->vexs[2].introduction ,"在女生宿舍旁边");
  strcpy(G->vexs[3].name ,"艺术学院");
  strcpy(G->vexs[3].introduction ,"音乐系、美术系,楼高4层;都在新校区呢");
  strcpy(G->vexs[4].name ,"行政楼");
  strcpy(G->vexs[4].introduction ,"行政办公大楼,楼高18层,别名主楼,盐师一大建筑");
  strcpy(G->vexs[5].name,"文学院");
  strcpy(G->vexs[5].introduction ,"文学院,楼高6层");
  strcpy(G->vexs[6].name ,"体育楼");
  strcpy(G->vexs[6].introduction ,"操场旁边,4号男生宿舍楼前面,考验与体育集中营");
  strcpy(G->vexs[7].name,"教育科学学院");
  strcpy(G->vexs[7].introduction ,"主楼里面");
  strcpy(G->vexs[8].name ,"南区学生宿舍");
  strcpy(G->vexs[8].introduction ,"离西南门近,男女都有");
  strcpy(G->vexs[9].name, "数学与经济管理学院");
  strcpy(G->vexs[9].introduction ,  "主楼里面");
  strcpy(G->vexs[10].name ,"中区7号楼");
  strcpy(G->vexs[10].introduction ,"比较旧,里面冬天狂冷;离学生1、2食堂近");
  strcpy(G->vexs[11].name ,"喷泉池");
  strcpy(G->vexs[11].introduction ,"很漂亮的哦,还有古亭,古味~");
  strcpy(G->vexs[12].name ,"体育系");
  strcpy(G->vexs[12].introduction ,"我也不知道在哪儿?");
  strcpy(G->vexs[13].name ,"游泳馆");
  strcpy(G->vexs[13].introduction ,"学校还没有建呢");
  strcpy(G->vexs[14].name ,"报告厅、阶梯教室");
  strcpy(G->vexs[14].introduction ,"主楼里面,可举办中、大型学术会议。/t/t/t/t有大小报告厅1-6个、阶梯教室1-6个");
  strcpy(G->vexs[15].name ,"南园大礼堂");
  strcpy(G->vexs[15].introduction ,"文艺演出所在地、室内运动场");
  strcpy(G->vexs[16].name ,"1食堂");
  strcpy(G->vexs[16].introduction ,"教工食堂及学生1食堂在此");
  strcpy(G->vexs[17].name ,"新图书馆");
  strcpy(G->vexs[17].introduction ,"建筑面积46000平方米");
  strcpy(G->vexs[18].name ,"2食堂");
  strcpy(G->vexs[18].introduction ,"学校东区,学生食堂");
  strcpy(G->vexs[19].name ,"东区学生宿舍");
  strcpy(G->vexs[19].introduction ,"离学生2食堂近");
  strcpy(G->vexs[20].name ,"计算机学院");
  strcpy(G->vexs[20].introduction ,"计算机学院大楼,楼高5层,原物电楼5号");
  strcpy(G->vexs[21].name, "教工宿舍");
  strcpy(G->vexs[21].introduction, "学校青年教职工租住地");
  strcpy(G->vexs[22].name ,"西区学生宿舍");
  strcpy(G->vexs[22].introduction ,"离学生3、4食堂近");
  strcpy(G->vexs[23].name ,"3食堂");
  strcpy(G->vexs[23].introduction ,"学校西区,学生食堂");
  strcpy(G->vexs[24].name ,"外国语学院");
  strcpy(G->vexs[24].introduction ,"外国语学院大楼,8号楼,比较破旧");
  strcpy(G->vexs[25].name ,"4食堂");
  strcpy(G->vexs[25].introduction, "学校西区,学生食堂,人气较高");
  strcpy(G->vexs[26].name, "校医院");
  strcpy(G->vexs[26].introduction ,"看小病的地方");
  strcpy(G->vexs[27].name ,"实验楼");
  strcpy(G->vexs[27].introduction ,"物电学院、化学与生命科学学院、/n/t/t/t/t机电系、建材系所在地,机房及多媒体教室若干");
 
 
  /*依次输入边上的权值信息*/
 for(i = 0;i < G->vexnum; i++)
   for(j = 0; j < G->vexnum; j++)
   {
    G->arcs[i][j].adj = INFINITY; /*先初始化图的邻接矩阵*/
    G->arcs[i][i].adj = 0;
   }
      
  /*部分弧长*/
 
  G->arcs[0][2].adj=50;   
  G->arcs[0][3].adj=60;      

  G->arcs[1][4].adj=90;    

  G->arcs[2][3].adj=60;   
  G->arcs[2][8].adj=40;     
 
  G->arcs[3][4].adj=60;   
  G->arcs[3][6].adj=40; 
      
  G->arcs[4][5].adj=70;   
  G->arcs[4][9].adj=70;   
  G->arcs[4][10].adj=80;  
  G->arcs[4][17].adj=200;

  G->arcs[5][7].adj=70;      

  G->arcs[6][9].adj=40;   
 
  G->arcs[7][18].adj=190;  

  G->arcs[8][11].adj=50;   

  G->arcs[9][12].adj=40;   
 
  G->arcs[10][18].adj=70;   
 
  G->arcs[11][12].adj=60;
  G->arcs[11][14].adj=50;  
  G->arcs[11][15].adj=50;

  G->arcs[12][16].adj=50;    
 
  G->arcs[13][14].adj=40;
  G->arcs[13][22].adj=60; 
 
  G->arcs[14][15].adj=50;
  G->arcs[14][20].adj=90;
 
  G->arcs[15][16].adj=60;
  G->arcs[15][21].adj=40;

  G->arcs[16][17].adj=60;
 
  G->arcs[17][18].adj=80;     
 
  G->arcs[18][19].adj=60;

  G->arcs[20][21].adj=60;
  G->arcs[20][24].adj=80;  
 
  G->arcs[22][23].adj=60;  
  G->arcs[22][25].adj=80;

  G->arcs[23][24].adj=60;  
 
  G->arcs[24][26].adj=100; 
  G->arcs[24][27].adj=100;
 
  G->arcs[25][26].adj=90; 
 
  G->arcs[26][27].adj=90;

  for(i=0;i<G->vexnum ;i++)                      /*邻接矩阵是对称矩阵,对称赋值*/
   for(j=0;j<G->vexnum ;j++)
    G->arcs[j][i].adj = G->arcs[i][j].adj;
}
void Search(MGraph *G)
{
    int code, flag = 1;
    printf("请输入要查询景点的编号:");
    scanf("%d", &code);
    getchar();
    while(flag)
    {
        if((code - 1) < 0 || (code - 1) >= G->vexnum)
        {
            printf("景点不存在丫!请重新输入景点编号:/n");
            scanf("%d", &code);
            getchar();
        }
        if((code - 1) >= 0 && (code - 1) < G->vexnum)
        {
            flag = 0;           
        }
    }
    code = code - 1;
    printf("/n *********************************************/n");
    printf("***编号**********景点名称*******简介*******************/n");
    printf("   %d             %s            %s/n", G->vexs[code].code, G->vexs[code].name, G->vexs[code].introduction);
    printf("*************************************************/n");
}
void ShortestPath_DJS(MGraph *G)
{
    int v, w, ivex, min, t = 0, x, flag=1,v0;
    int final[MAX_VERTEX_NUM], dist[MAX_VERTEX_NUM], ps[MAX_VERTEX_NUM][MAX_VERTEX_NUM];
    printf("请输入一个起始顶点(1~%d之间)编号:", G->vexnum);
    scanf("%d", &v0);
    getchar();
    while(flag)
    {
        if((v0 - 1) < 0 || (v0 - 1) >= G->vexnum)
        {
            printf("此景点不存在丫!请重新输入景点编号:");
            scanf("%d", &v0);
            getchar();
        }
        if((v0 - 1) >= 0 && (v0 - 1) < G->vexnum)       
            flag = 0;
    }
    v0 = v0 - 1;
   
    for(v = 0; v < G->vexnum; v++)
    {
        final[v] = 0;
        dist[v] = G->arcs[v0][v].adj;
       
        for(w = 0; w < G->vexnum; w++)
        {
            ps[v][w] = 0;
        }
        if(dist[v] < INFINITY)
        {
            ps[v][v0] = 1;
            ps[v][v] = 1;
        }
    }
    dist[v0] = 0;
    final[v0] = 1;
    for(ivex = 1; ivex < G->vexnum; ivex++)
    {
        min = INFINITY;
        for(w = 0; w < G->vexnum; w++)
        {
            if(!final[w])
                if(dist[w] < min)
                {
                    v = w;
                    min = dist[w];               
                }
        }
        final[v] = 1;
        for(w = 0; w < G->vexnum; w++)
        {
            if(!final[w] && (min + G->arcs[v][w].adj < dist[w]))
            {
                dist[w] = min + G->arcs[v][w].adj;
                for(x = 0; x < G->vexnum; x++)
                {
                    ps[w][x] = ps[v][x];
                }
                ps[w][w] = 1;
            }
        }
        for(v = 0; v < G->vexnum; v++)
        {
            if(v0 != v) printf("%s", G->vexs[v0].name);
            for(w = 0; w < G->vexnum; w++)
            {
                if(ps[v][w] && w != v0)
                    printf("-->%s", G->vexs[w].name);
                t++;
            }
            if(t > G->vexnum-1 && v0 != v)
            {
                 printf("        总路线长度:%dm/n/n", dist[v]);
            }
        }
    }
}    /*end of ShortestPath_DIJ*/

void Floyd(MGraph *G)
{
    int  v, u, i, w, start, end, flag = 1, ps[MAX_VERTEX_NUM][MAX_VERTEX_NUM][MAX_VERTEX_NUM], dist[MAX_VERTEX_NUM][MAX_VERTEX_NUM];
    for(v = 0; v < G->vexnum; v++)
        for(w = 0; w < G->vexnum; w++)
    {
        dist[v][w] = G->arcs[v][w].adj;
        for(u = 0; u < G->vexnum; u++)
        {
            ps[v][w][u] = 0;
        }
        if(dist[v][w] < INFINITY)
        {
            ps[v][w][v] = 1;
            ps[v][w][w] = 1;   
        }
    }
    for(u = 0; u < G->vexnum; u++)
        for(v = 0; v < G->vexnum; v++)
            for(w = 0; w < G->vexnum; w++)
                if(dist[v][u] + dist[u][w] < dist[v][w])
                {
                    dist[v][w] = dist[v][u] + dist[u][w];
                    for(i = 0; i < G->vexnum; i++)
                    {
                        ps[v][w][i] = ps[v][u][i] || ps[u][w][i];
                    }
                }
    printf("/n请输入出发点和目的地(1~%d之间)的编号:", G->vexnum);
    scanf("%d%d", &start, &end);
    getchar();
    while(flag)
    {
        if((start - 1) < 0 || ((start-1) >= G->vexnum) || (end - 1) < 0 || (end -1)>= G->vexnum)
        {
            printf("此景点不存在丫!请重新输入出发点和目的地(1~%d之间)的编号:", G->vexnum);
            scanf("%d%d", &start, &end);
            getchar();
        }
        if(((start - 1) >= 0 && ((start-1) < G->vexnum)) && ((end - 1) >= 0 && (end -1) < G->vexnum))
        {
            flag = 0;
        }
    }
    start = start - 1;
    end = end - 1;
    printf("%s", G->vexs[start].name);
    for(u = 0; u < G->vexnum; u++)
        if(ps[start][end][u] && start != u && end != u)
            printf("-->%s", G->vexs[u].name);
    printf("-->%s", G->vexs[end].name);
    printf("总路线长度:%dm/n", dist[start][end]);
}    /*Floyd end*/
                                                             <完>

实现简单的查询,各风景的查询,调用各函数,实现课程设计的目标。其中包含三个功能,一个是直接进入导航系统,利用主函数中已有的数据,进行查询:一个是进行创建数据,本程序中初始数据为农大的导航数据,如果需要也可以自己建立一个;最后一个是退出功能。设计该函数的目的是为了能够多次得应用dijkstra函数进行查询最短路径。同时该函数可以列出各景点的代号和对应的名称,这样大家只要输入代号就行了。方便进行查询。下面分别描述这些函数,建立它们函数原型。 1、主函数 函数原型:void main(void) 功 能:控制程序。 参 数:void 返 回 值:void 要 求:管理菜单命令并完成初始化。 2、菜单选择和处理函数 函数原型:int menu() 功 能:处理选择的菜单命令并接收用户选择的命令代码。 参 数:int 返 回 值:int 工作方式:返回命令代码的整数值,根据命令,调用相应函数。 要 求:只允许选择规定键,如果输入不合要求,则提醒用户重新输入。 3、建立邻接矩阵函数 函数原型:void createadj() 功 能:重新建立一个学生信息的记录。 参 数:void 返 回 值:void 工作方式:在需要的时候就可以有主菜单中调用 void createadj()函数。 要 求:必需输入信息记录,然后才能调用出search()函数进行查询。 4、dijkstra函数 函数原型:void dijkstra(intx,inty) 功 能:求两点间的最短路径 参 数:void 返 回 值:void 工作方式: 该函数被其它一些函数调用。 5、结束程序 函数原型:int Exit() 功 能:使程序正常结束运行 参 数:int 返 回 值:1 工作方式:在操作都完成后,可以调用int Exit()函数,使函数最终返回 1 运行exit(1),程序正常结束。 要 求:运行Exit()函数后可以选择是否要保存,选择y则先保存再返 回1值;如果选择n直接返回1值。详细的程序设计应从下到上,在本设计中就要先设计createadj函数;然后设计dijkstra函数;接着是search函数;menu函数;最后才是main函数。如此设计能大大提升设计速度,因为从下往上使编程时的高试过程简单许多,而做课程设计花费时间最多的就是调试过程。对于各函数的详细设计,各函数的N—S如下: (1)Createadj函数 (2)Dijkstra函数          (3)Search函数          (4)Menu函数          (5)main函数          2.4 程序编码   把详细设计的结果进一步求精为程序设计语言程序。同时加入一些注解和断言,使程序中逻辑概念清楚;编写过程中参考各种的教材和材料,使程序编写的正确性大有提高,同时也许到许多实践知识,增加了实践经验。 2.5 程序调试与测试    程序编写总是出现各种各样的错误,但是难点不是修改错误,而是找出错误。在大量的源程序中找出错误难度很大,但有了一定的方法,就能节省大量的时间,在这次课程设计中我运用的调试方法主要有2种:     一是借助调试工具。利用Turbo C中提供的程序专门调试工具Debugger程序,可以很容易找出程序中的各种语法错误。但是遇到一些逻辑错误时却又无从着手。这时我就用下面一种方法。     二是在程序中插入打印语句。猜测出大致的错误位置,选则一些主要变量,在关键部位插入打印语句,打印出这个主要变量,看其是否与理论上的一样,在多个位置插入,如果有个位置的值与理论值一样,另一个位置与理论值不一样,则错误就落在这两个位置之间,然后再多测试几个位置缩小范围,直到找出错误。  例如;我在调试main()主函数时,程序能够运行,三个选项都能选择,创建函数能够正常运行,也能正常退出,但在选第一条进入校园导航后,打印出来的列表却是空的,源程序中的初始化数据没有显示出来,我又尝试输入两个结点进行查找,发现没有输出路线,所以我猜测初始化数据没有被正常写入。但不知道为何没有被正常写入,首先怀疑是初始化时附值发生错误,查阅各种资料进行校验,发现没有错误。后来经过综合分析,发现最有可能是n值在search()函数中发生错误,于是我在search()函数中插入打印n 的语句,运行后发现输出的n为0,初始化数据中有11个结点,n应该为11,所以n 在这个地方发生错误,我又在main()主函数中打印出n 的值,n=11,是正确的。所以错误就在search()函数中,也就说是当运行case1,运行到search()函数时,n从11变为0,针对这个错误,我把变量n改为宏定义,因为n 是代表结点个数,不管在哪个函数中它的值都是一样的才对。改完后运行程序,成功! 本设计文件的注释如上,已给出详细的说明,下面仅以文件为单位说明各个函数的作用和特点,在必要的地方给予一定说明。  3.1、guide.h文件 使用条件编译。以下是头文件中语句 /********************************************* *头文件(.h) ********************************************/ #include "stdio.h" #include "conio.h" #include "alloc.h" #define n0 100 #define infi 32767 /*“无穷大*/ int adjmatrix[n0+1][n0+1];     /*邻接矩阵*/ int n=11; struct node             /*表结点*/ { char name[20];       /*下一个表结点与它们之间的距离*/ }place[12]={{"ShiDiGongYuan"},   /*表结点初始化,即写各景点名称*/    {"CangRongGongYu"},    {"YinHuiLou"},    {"TuoHuanGuanChang"},    {"DiBaShiTang"},    {"XiaoYiYuan"},    {"TuShuGuan"},    {"TiYuGuan"},    {"ZhongHuaGuanChang"},    {"ChuangXinLou"},    {"YiFuTuShuGuan"},    {"BoXueLou"}};  void createadj()          /*建立邻接表*/  void dijkstra( int x,int y)     /*dijkstra求最小生树*/  void search()            /*搜索最短路径*/  menu()               /*菜单函数*/          /********************************************* *建立邻接表 ********************************************/ void createadj()  
评论 15
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值