/*
烟台大学计算机学院
作者:董玉祥
时间:2017 12 21
*/
main.cpp
#include <stdio.h>
#include <malloc.h>
#include "graph.h"
#include "link.h"
int main()
{
Graph *g;
g=(Graph*)malloc(sizeof(Graph));
//初始的七个景点
JD jd[MAXV]=
{
0,"三元湖","\n三元湖位于*****\n****************\n***************",
1,"钟楼","\n钟楼位于 *******\n*************\n**************",
2,"综合楼","\n综合楼位于 *****\n***********\n**************",
3,"八景园","\n八景园位于*******\n**********\n**************",
4,"七餐","\n七餐位于********\n*************\n**************",
5,"南门","\n南门位于**********\n***********\n**************",
6,"厕所","\n厕所位于******\n************\n**********",
};
//景点间的距离
int juli[MAXV][MAXV]=
{
0,4,6,6,x,x,x,
4,0,1,x,7,x,x,
6,1,0,x,6,4,x,
6,x,x,0,x,5,x,
x,7,6,x,0,x,6,
x,x,4,5,x,0,8,
x,x,x,x,6,8,0
};
g->n=MAXV;
CreateGraph(g,jd,juli);
menu(g);
return 0;
}
graph.h
#ifndef GRAPH_H_INCLUDED
#define GRAPH_H_INCLUDED
#include "link.h"
#define MAX 100
#define MAXV 7
#define x 9999
typedef struct //地点编号,名字,,其他,,
{
int number;
char name[20];
char info[200];
} VertexType;
typedef struct
{
int n,e; //n 地点数 e 边数
int edges[MAX][MAX]; //存放地点间的距离
VertexType vexs[MAX]; //存放地点的其他信息
} Graph;
void CreateGraph(Graph *g,JD jd[],int juli[][MAXV]); //将景点信息,距离等入图
void DispGraph(Graph *g); //输出地点。。
void Ppath(Graph *g,int path[],int i,int v);
void Dispath(Graph *g,int dist[],int path[],int s[],int n,int v);//s[]判断点是否加入 path[]该最小路径点的编号 dist[]该点的最小路径
void Dijkstra(Graph *g,int v); //狄克斯特拉算法求最短路径
void menu(Graph *g);
void Guanliyuancaozuo(Graph *g); //管理员操作
void Adddidian(Graph *&g); //增添地点
void genggai(Graph *&g); //更改地点
void shanchu(Graph *&g); //删除地点
void Yonghucaozuo(Graph *g); //用户操作
void jingdian(Graph *g);
void lujingchaxun(Graph *g); //狄克斯特拉算法求最短路径
void then(Graph *g); //1.退出 2.返回 3.返回主菜单 等操作
#endif // GRAPH_H_INCLUDED
link.h
#ifndef LINK_H_INCLUDED
#define LINK_H_INCLUDED
typedef struct //顺序表进行地点信息输入
{
int number;
char name[20];
char info[500];
}JD;
#endif // LINK_H_INCLUDED
graph.cpp
#include <stdio.h>
#include "graph.h"
#include "link.h"
void CreateGraph(Graph *g,JD jd[],int juli[][MAXV]) //建立图
{
int i,j;
for(i=0;i<g->n; i++) //将顺序表存储数据入图
{
g->vexs[i].number=jd[i].number;
for(j=0; jd[i].name[j]!='\0'; j++)
g->vexs[i].name[j]=jd[i].name[j];
for(j=0; jd[i].info[j]!='\0'; j++)
g->vexs[i].info[j]=jd[i].info[j];
}
for(i=0; i<g->n; i++) //将景点间距离存入矩阵
for(j=0; j<g->n; j++)
{
g->edges[i][j]=juli[i][j];
}
}
void DispGraph(Graph *g) //显示个地点
{
int i;
printf(" 以下为本校区的各个地点:\n");
for(i=0; i<g->n; i++)
{
printf(" %d. %s ",g->vexs[i].number,g->vexs[i].name);
if((i+1)%3==0)
printf("\n");
}
printf("\n");
printf(" %d.返回 %d.返回主菜单\n",i,i+1);
}
void then(Graph *g) //1.退出 2.返回 3.返回主菜单 等操作
{
int i;
printf("1.退出 2.返回 3.返回主菜单\n");
scanf("%d",&i);
if(i==1) printf("欢迎下次使用\n");
if(i==2) Yonghucaozuo(g);
if(i==3) menu(g);
else
{
printf("输入错误,请重新输入:");
then(g);
}
}
void Ppath(Graph *g,int path[],int i,int v) //前向递归查找路径上的顶点
{
int k;
k=path[i];
if (k==v) return; //找到了起点则返回
Ppath(g,path,k,v); //找顶点k的前一个顶点
printf("%s,",g->vexs[k].name); //输出顶点k
}
void Dispath(Graph *g,int dist[],int path[],int s[],int n,int v)//s[]判断点是否加入 path[]该最小路径点的编号 dist[]该点的最小路径
{
int i;
for (i=0; i<n; i++)
if (s[i]==1)
{
if(v==i)
{
printf(" 从%d.%s到%d.%s的最短路径长度为:0 \t路径为:",v,g->vexs[v].name,i,g->vexs[i].name);
printf("%s,%s",g->vexs[v].name,g->vexs[v].name);
printf("\n");
}
else
{
printf(" 从%d.%s到%d.%s的最短路径长度为:%d \t路径为:",v,g->vexs[v].name,i,g->vexs[i].name,dist[i]);
printf("%s,",g->vexs[v].name); //输出路径上的起点
Ppath(g,path,i,v); //输出路径上的中间点
printf("%s\n",g->vexs[i].name); //输出路径上的终点
}
}
else
printf("从%d.%s到%d.%s不存在路径\n",v,g->vexs[v].name,i,g->vexs[i].name);
}
void Dijkstra(Graph *g,int v) //dist[]存放最短路径 path[]存放通过的点编号 s[]判断点是否加入s[]
{
int dist[g->n],path[g->n];
int s[g->n];
int min,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]<x) //路径初始化 存在路径path[]置v 不存在置-1
path[i]=v;
else
path[i]=-1;
}
s[v]=1; //v点已加入
path[v]=0;
for (i=0; i<g->n; i++) //循环直到所有顶点的最短路径都求出
{
min=x; //min置最小长度初值
for (j=0; j<g->n; j++) //选取不在s中且具有最小距离的顶点u
if (s[j]==0 && dist[j]<min)
{
u=j;
min=dist[j];
}
s[u]=1; //顶点u加入s中
for (j=0; j<g->n; j++) //修改不在s中的顶点的距离
if (s[j]==0)
if (g->edges[u][j]<x && dist[u]+g->edges[u][j]<dist[j])
{
dist[j]=dist[u]+g->edges[u][j];
path[j]=u;
}
}
Dispath(g,dist,path,s,g->n,v); //输出最短路径
}
void lujingchaxun(Graph *g) //求最短路径
{
int i;
printf("请输入您的地点起点编号:");
scanf("%d",&i);
if(i>g->n-1)
{
printf("输入错误,请重新输入:");
lujingchaxun(g);
}
else
{
Dijkstra(g,i);
then(g);
}
}
void menu(Graph *g) //用户 管理员
{
printf(" ********欢迎进入校园导游系统*******\n");
printf("1.管理员\t2.用户\n");
printf("请输入:");
int i;
scanf("%d",&i);
switch(i)
{
case 1:
Guanliyuancaozuo(g);
break;
case 2:
Yonghucaozuo(g);
break;
default :
printf("输入错误,请重新输入:\n");
menu(g);
}
}
void Guanliyuancaozuo(Graph *g) //管理员操作
{
printf("1.地点增添 2.地点信息更改 3.地点删除 4.返回\n");
int i;
scanf("%d",&i);
switch(i)
{
case 1:
Adddidian(g);
menu(g);
break;
case 2:
genggai(g);
menu(g);
break;
case 3:
shanchu(g);
menu(g);
break;
case 4:
menu(g);
break;
default:
printf("输入错误请重新输入:\n");
Guanliyuancaozuo(g);
}
}
void Adddidian(Graph *&g) //增添地点
{
char n[20];
char info[200];
int juli;
int i;
printf("请输入地点名称:");
scanf("%s",n);
for(i=0; n[i]!='\0'; i++)
{
g->vexs[g->n].name[i]=n[i];
}
printf("请输入地点信息:");
scanf("%s",info);
for(i=0; info[i]!='\0'; i++)
{
g->vexs[g->n].info[i]=info[i];
}
printf("此地点编号为%d,请输入%d点到各个点的距离:\n",g->n,g->n);
g->vexs[g->n].number=g->n;
g->n++;
for(i=0; i<g->n; i++)
{
printf("%d到%d的距离为:",g->n-1,i);
scanf("%d",&juli);
printf("\n");
g->edges[g->n-1][i]=juli;
g->edges[i][g->n-1]=juli;
}
}
void genggai(Graph *&g) //更改地点
{
int n,i,j,k,juli;
char na[20];
char nu[200];
printf("请输入您要修改的地点编号:");
scanf("%d",&n);
printf("\n");
printf("请输入新的名称:");
scanf("%s",na);
for(i=0; na[i]!='\0'; i++)
g->vexs[n].name[i]=na[i];
k=i;
if(k<20)
{
for(k; k<20; k++)
g->vexs[n].name[k]='\0';
}
printf("\n");
printf("请输入新的名称的信息:");
scanf("%s",nu);
for(j=0; nu[j]!='\0'; j++)
g->vexs[n].info[j]=nu[j];
if(j<200)
{
for(j; j<200; j++)
g->vexs[n].info[j]='\0';
}
for(i=0; i<g->n; i++)
{
printf("%d到%d的距离为:",n,i);
scanf("%d",&juli);
printf("\n");
g->edges[n][i]=juli;
g->edges[i][n]=juli;
}
printf("更改成功\n");
}
void shanchu(Graph *&g) //删除地点
{
int n,i;
printf("请输入您要删除的地点编号:");
scanf("%d",&n);
if(n>=g->n)
{
printf("你输入的编号地点不存在,请重新输入:\n");
shanchu(g);
}
else
{
int j=n;
int p=n;
while(n<g->n)
{
g->vexs[n]=g->vexs[n+1];
g->vexs[n].number=n;
n++;
}
for(j; j<g->n-1; j++)
for(i=0; i<g->n-1; i++)
{
if(i>=p)
{
g->edges[j][i]=g->edges[j+1][i+1];
g->edges[i][j]=g->edges[i+1][j+1];
}
else
{
g->edges[j][i]=g->edges[j+1][i];
g->edges[i][j]=g->edges[i][j+1];
}
}
g->n--;
printf("删除成功\n");
}
}
void Yonghucaozuo(Graph *g) //用户操作
{
printf(" 1.地点查询 2.路程查询\n");
printf("请输入操作编号:");
int caozuo;
scanf("%d",&caozuo);
switch(caozuo)
{
case 1:
DispGraph(g);
jingdian(g);
break;
case 2:
lujingchaxun(g);
break;
default :
printf("输入错误,请重新输入:\n");
Yonghucaozuo(g);
}
}
void jingdian(Graph *g) //输出景点的信息
{
int number;
printf("请输入编号:");
scanf("%d",&number);
if(number>g->n+1)
{
printf("输入错误请重新输入:\n");
jingdian(g);
}
else if(number==g->n+1)
{
menu(g);
}
else if(number==g->n)
{
Yonghucaozuo(g);
}
else
{
printf("%s %s",g->vexs[number].name,g->vexs[number].info);
printf("\n");
then(g);
}
}