设计目的:在校园建设不断完善的现在,为在校学生提供合适的行走路径,为来访的客人提供各种服务的信息;对于这些问题,可用图结构来表示校园交通网络,编写程序完成校园导游系统。
设计内容: 提供用户以及管理员功能,用户可以对校园地点进行查询,而管理员可以对交通图进行增删查改,同时管理员可以登陆、修改密码等待操作,有一定的交互界面。
校园导游图涉及了地点和道路两方面信息,地点信息以及道路信息应存储在文件中,文件的存储格式自己设计。对这两方面进行查找、增加、修改、删除等操作,并同步更新文件。
1. 设计并显示学校的校园平面图,
地点(地点名称、地点介绍),
路线(公里数),相关信息不少于10个。(文件存储)
2. 提供图中任意地点相关信息的查询。
3. 提供图中任意地点的问路查询:
(1) 任意两个地点之间的所有简单路径;
(2) 任意两个地点之间的一条最短的简单路径;
(最短路径长度——中转次数最少)
(3) 任意两个地点之间的一条最佳访问路线。
(带权(公里数)最短路径长度)
4. 提供图中所有地点的最佳布网方案(最小生成树);
5. 增加新地点和路线、撤销旧地点和路线。
基本实现上述内容。代码未整理(懒得-_-),直接可以在devc++跑,无需任何调整
#include
#include
#include
#define MAX_VERTEX_NUM 30
#define maxn 10
//顶点信息
typedef struct{
int vexNum; // 编号
char name[30]; //名称
char info[70]; //介绍
char haha[10]; //推荐指数
}VexInfo;
//边
typedef struct ArcNode{
int adjvex;//该顶点在顶点数组中下标 从1开始
int weight;//用于储存权值
struct ArcNode *nextarc; //指向下一条边
}ArcNode;
//顶点
typedef struct VNode{
VexInfo vex[MAX_VERTEX_NUM]; //顶点信息
ArcNode *firstarc;//指向第一条依附该顶点的边的指针
}VNode;
//网
typedef struct{
VNode vnodes[MAX_VERTEX_NUM];//顶点数组
int vexnum;//顶点数
int arcnum;//边数
}ALGraph;
//栈的结构体
typedef struct
{
int top;
int num[maxn];
}Stack;
void regist();//注册
void login();//登录
void printPlace(ALGraph G);//打印节点
int numi=0;
int stacks[20][20] = {
0};//存所有路径
int stackTops[20] = {
};//存每条路径的节点数
//解决scanf缓冲区问题
static void eatline(void)
{
while (getchar() != '\n')
continue;
}
//初始化栈
Stack* init()
{
Stack *s;
s = (Stack*)malloc(sizeof(Stack));
if(s==NULL)
{
printf("分配失败\n");
return 0;
}
s->top=-1;
return s;
}
//入
void push(Stack *s,int v)
{
if(s->top == maxn -1)
return;
s->num[++s->top] = v;
}
//退
int pop(Stack *s)
{
if(s->top == -1)
return -1;
else
return s->num[s->top--];
}
//查看顶点是否在栈中
int check(Stack *s,int v)
{
int i;
for(i=0;i<=s->top;i++)
{
if(v==s->num[i])
return 1;
}
return 0;
}
//输出栈内数据,也就是路径
void show(Stack* s,ALGraph G)
{
int m = s->top;
int a = 0;
int i = s->num[a++];
printf("|%d.%s|",i,G.vnodes[i].vex[i].name);
while(a<=m)
{
i = s->num[a++];
printf("-->|%d.%s|",i,G.vnodes[i].vex[i].name);
}
printf("\t\t共|%d|个地点",stackTops[numi++]+1);
printf("\n\n");
}
//找到该结点紧邻的下一个顶点
int findnext(ALGraph G,int i,int v)
{
ArcNode *p,*q;
if(G.vnodes[v].firstarc)
{
p=G.vnodes[v].firstarc;
while(p->adjvex!=i)
p=p->nextarc;
q = p->nextarc;
if(q)
{
return q->adjvex;
}
else
return -1;
}
else
return -1;
}
//找到该结点紧邻的第一个顶点
int findfirst(ALGraph G,int i)
{
ArcNode *p;
if(G.vnodes[i].firstarc)
{
p=G.vnodes[i].firstarc;
return p->adjvex;
}
else
{
return -1;
}
}
int a=0,b=0,c=0;
//深度优先算法
void DFS(int B,int E,Stack* s,ALGraph G,int j){
int i,m,n;
push(s,B);
if(E==B){
if(j==2){
}
stackTops[c++] = s->top;
if(j==0)
show(s,G);
else {
while(b<=s->top){
stacks[a][b] = s->num[b];
b++;
}
a++;b=0;
printf("\n");
}
pop(s);
return;
}
i=findfirst(G,B);
for(;i!=-1;i=findnext(G,i,B)){
if(check(s,i)&&i!=E)
continue;
DFS(i,E,s,G,j);
}
pop(s);
}
int visit[30]={
0};
int sumWeight[30] = {
0};
int we = 0;
void findPath(ALGraph G, int u, int v, int path[], int d, int weight[]) {
int w;
ArcNode *p;
d++;
int i,j,m=30;
path[d] = u;
visit[u] = 1;
if (u == v) {
int temp = 0;
for(i = 1 ; i<d;i++){
temp += weight[i];
// printf("%d ",weight[i]);
}
//printf("\n");
sumWeight[we++] = temp;
//
// i=1;
// printf("|%d.%s|",path[i],G.vnodes[path[i]].vex[path[i]].name);
// for (i = 1; i <= d; i++) {
// printf("-->|%d.%s|",path[i],G.vnodes[path[i]].vex[path[i]].name);
//
// }
// while(path[i]!=0 && path[i] != v){
for(i=1;i<=d;){
stacks[a][b] = path[i];
//printf("%d ",stacks[a][b]);
b++;i++;
}
a++;b=0;
}
p = G.vnodes[u].firstarc;
while (p) {
w = p->adjvex;
if (!visit[w]) {
weight[d] += p->weight;
//printf("weight %d d=%d ",weight[d],d);
findPath(G, w, v, path,d, weight);
}
p = p->nextarc;
}
visit[u] = 0;
}
void query(ALGraph G,char name[],int i){
int w,e;
int h=0,o=0,p=0,g=0;
int flag = 1;
Stack *s;
s = init();
while(flag == 1){
printPlace(G);
printf("\n\t\t\t\t输入起点编号:");
scanf("%d",&w);
printf("\t\t\t\t输入终点编号:");
scanf("%d",&e);
if (w > G.vexnum || w <= 0 || e > G.vexnum || e < 0 || w == e){
printf( "\t\t\t\t\t\t输入错误!\n\n" );
}
else{
printf("\n\t\t\t\t\t从%s到%s的[%s]:\n\n\n", G.vnodes[w].vex[w].name, G.vnodes[e].vex[e].name,name);
if(i==2){
int path[30] = {
0};
int weight[30] = {
0};
int sum = 0;
int t = 0;
findPath(G,w,e,path,t,weight);
o = sumWeight[h];
while(sumWeight[++h]!=0){
if(sumWeight[h]<o){
o = sumWeight[h];
g = h;
}
}
int d = stacks[g][p];
printf("|%d.%s|",d,G.vnodes[d].vex[d].name);
while(stacks[g][++p]!=0){
d = stacks[g][p];
printf("-->|%d.%s|",d,G.vnodes[d].vex[d].name);
}
printf("\t权值总和为:|%d|",o);
printf("\n");
stacks[h][p] = {
0};
}else{
DFS(w,e,s,G,i);//调用函数进行实现功能
}
}
if(i==1){
o = stackTops[h];
while(stackTops[++h]!=0){
if(stackTops[h]<o){
o = stackTops[h];
g = h;
}
}
int d = stacks[g][p];
printf("|%d.%s|",d,G.vnodes[d].vex[d].name);
while(stacks[g][++p]!=0){
d = stacks[g][p];
printf("-->|%d.%s|",d,G.vnodes[d].vex[d].name);
}
printf("\t\t共|%d|个地点",o+1);
printf("\n\n");
}
printf("\n\n\t\t\t\t\t 输入0退回上级菜单,输入1继续:" );
scanf("%d", &flag);
system("cls");
}
system("cls");
}
void queryAllPath(ALGraph G){
system("cls");
int i = 0;
char name[15] = {
"所有简单路径有"};
printf( "\t\t\t\t——————所有简单路径查询——————\n" );
query(G,name,i);
}
void queryLitterVe(ALGraph G){
system("cls");
int i = 1;
char name[30] = {
"最短的简单路径(中转最少)是"};
printf( "\t\t\t\t——————最短的简单路径(中转最少)——————\n" );
query(G,name,i);
}
void queryPathWithWe(ALGraph G){
system("cls");
int i = 2;
char name[30] = {
"最佳访问路径(权值和最小)是"};
printf( "\t\t\t\t——————最佳访问路径(权值和最小)——————\n" );
query(G,name,i);
}
void queryPath(ALGraph G){
int x,flag = 1;
while(flag == 1){
//二级菜单
printf("\t\t\t|--------------问路查询---------------|\n");
printf("\t\t\t| |\n");
printf("\t\t\t| 1. 所有简单路径 |\n");
printf("\t\t\t| 2. 最短的简单路径(中转最少) |\n");
printf("\t\t\t| 3. 最佳访问路径(权值和最小) |\n");
printf("\t\t\t| |\n");
printf("\t\t\t|-------------------------------------|\n\n");
printf("\t\t\t请选择您需要的操作,输入0返回上级菜单:");
scanf("%d",&x);
switch(x){
case 1: system("cls");queryAllPath(G);break;
case 2: system("cls");queryLitterVe(G);break;
case 3: system("cls");queryPathWithWe(G);break;
case 0: flag = 0; break;
default:printf( "\t\t\t\t\t\t\t输入信息错误,请重新输入!\n" ); break;
}
system("cls");
}
}
//存储校园地图
void createMapFile(){
char filename[30] = "schoolmap.txt";
FILE *fp;
fp = fopen(filename,"wt");
if(fp == NULL)
{
printf("\n打开失败!");
exit(1);
}
fprintf(fp,"|------------------------------------------------西安邮电大学地图--------------------------------------------------|\n");
fprintf(fp,"|--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*---|\n");
fprintf(fp,"|***************|西区北门|**********************|东区西门|***************| 逸夫楼 | |\n");
fprintf(fp,"| * | | |\n");
fprintf(fp,"| * | | |\n");
fprintf(fp,"| |水煮鸽子| | |****|安美公寓| |\n");
fprintf(fp,"| * | | * |\n");
fprintf(fp,"| * *****|大学生活动中心| | | * |\n");
fprintf(fp,"| |教学楼|******** * * | |****|安悦公寓| |\n");
fprintf(fp,"| * ******|图书馆| | | * |\n");
fprintf(fp,"| |美食广场|************** * | |****************|大烟囱| |\n");
fprintf(fp,"| * * * | | * |\n");
fprintf(fp,"| * * * | |****|尚美造型| |\n");
fprintf(fp,"| |宿舍楼|*****|旭日苑| * | | |\n");
fprintf(fp,"| ************|西邮天桥|****************|东区食堂|****| | |\n");
fprintf(fp,"| ** ** | | |\n");
fprintf(fp,"| ** ** | | |\n");
fprintf(fp,"|***********************|西区?门|**************|东区?门|***************| | |\n");
fprintf(fp,"| | 家属区 | |\n");
fprintf(fp,"|--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*---|\n");
fprintf(fp,"|--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*---|\n");
fclose(fp);
}
//打印地图
void printMap(){
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 AdjFile(){
int i,j;
char filename[30] = "ArcInfo.txt";
char filename1[30] = "BiaoInfo.txt";
FILE *fp;
fp = fopen(filename,"wt");
if(fp == NULL){
printf("\n打开失败!");
exit(1);
}
FILE *fp1;
fp1 = fopen(filename1,"wt");
if(fp1 == NULL){
printf("\n打开失败!");
exit(1);
}
int vexnum = 11;
int arcnum = 13; //18个顶点,25个边
fprintf(fp1,"%d %d\n",vexnum,arcnum); //存入文件标记
//将邻接表弧的信息存入文件,上标,下标,权值
fprintf(fp,"%10d %10d %10d\n",11,1,300);
fprintf(fp,"%10d %10d %10d\n",6,8,180);
fprintf(fp,"%10d %10d %10d\n",8,9,50);
fprintf(fp,"%10d %10d %10d\n",9,10,70);
fprintf(fp,"%10d %10d %10d\n",10,11,230);
fprintf(fp,"%10d %10d %10d\n",7,11,200);
fprintf(fp,"%10d %10d %10d\n",1,2,100);
fprintf(fp,"%10d %10d %10d\n",2,3,20);
fprintf(fp,"%10d %10d %10d\n",3,4,20);
fprintf(fp,"%10d %10d %10d\n",4,5,30);
fprintf(fp,"%10d %10d %10d\n",5,6,70);
fprintf(fp,"%10d %10d %10d\n",6,7,150);
fprintf(fp,"%10d %10d %10d\n",7,8,60);
fclose(fp1);
fclose(fp);
}
void addressInfoFile(VNode G){
int i;
char filename[30] = "addressInfo.txt";
FILE *fp;
fp = fopen(filename,"wt");
if(fp == NULL){
printf("\n打开失败!");
exit(1);
}
G.vex[1].vexNum=1;
strcpy(G.vex[1].name,"东区西门");
strcpy(G.vex[1].info,"西安邮电大学长安校区东区的西门,现在只能走一边出去");
strcpy(G.vex[1].haha,"***");
G.vex[2].vexNum=2;
strcpy(G.vex[2].name,"逸夫楼");
strcpy(G.vex[2].info,"西安邮电大学东区教学楼,日常使用小o找路");
strcpy(G.vex[2].haha,"***");
G.vex[3].vexNum=3;
strcpy(G.vex[3].name,"安美公寓");
strcpy(G.vex[3].info,"分为安美公寓南楼和北楼");
strcpy(G.vex[3].haha,"****");
G.vex[4].vexNum=4;
strcpy(G.vex[4].name,"安悦公寓");
strcpy(G.vex[4].info,"分为安悦公寓南楼和北楼");
strcpy(G.vex[4].haha,"*****");
G.vex[5].vexNum=5;
strcpy(G.vex[5].name,"东升苑");
strcpy(G.vex[5].info,"西安邮电大学东区食堂");
strcpy(G.vex[5].haha,"***");
G.vex[6].vexNum=6;
strcpy(G.vex[6].name,"西邮天桥");
strcpy(G.vex[6].info,"连接西安邮电大学长安校区西区和东区的天桥,只有一半");
strcpy(G.vex[6].haha,"****");
G.vex[7].vexNum=7;
strcpy(G.vex[7].name,"图书馆");
strcpy(G.vex[7].info,"西安邮电大学图书馆,可以借阅书籍和自习");
strcpy(G.vex[7].haha,"*****");
G.vex[8].vexNum=8;
strcpy(G.vex[8].name,"体育馆");
strcpy(G.vex[8].info,"西安邮电大学室内运动场所");
strcpy(G.vex[8].haha,"*");
G.vex[9].vexNum=9;
strcpy(G.vex[9].name,"旭日苑");
strcpy(G.vex[9].info,"西安邮电大学西区食堂");
strcpy(G.vex[9].haha,"*****");
G.vex[10].vexNum=10;
strcpy(G.vex[10].name,"美食广场");
strcpy(G.vex[10].info,"西安邮电大学西区食堂");
strcpy(G.vex[10].haha,"****");
G.vex[11].vexNum=11;
strcpy(G.vex[11].name,"西区北门");
strcpy(G.vex[11].info,"西安邮电大学西区的门");
strcpy(G.vex[11].haha,"****");
//把信息存到文件中
for(i = 1; i <= 11; i++){
fprintf(fp,"%s\n%s\n%s\n",G.vex[i].name,G.vex[i].info,G.vex[i].haha);
}
fclose(fp);
}
int LocateVex(ALGraph G,int v){
//定位函数
for(int i=0;i<G.vexnum;i++){
if(v==G.vnodes[i].vex[i].vexNum)return i;
}
}
void Create(ALGraph &G){
ArcNode *p,*q;
int i,j,k,w,v1,v2;
char name[30];
char info[70];
char haha[10];
FILE *fp1;
fp1 = fopen("BiaoInfo.txt","rt");
if(fp1 == NULL){
printf("\n打开失败!");
exit(1);
}
FILE *fp2;
fp2 = fopen("ArcInfo.txt","rt");
if(fp2 == NULL){
printf("\n打开失败!");
exit(1);
}
FILE *fp3;
fp3 = fopen("addressInfo.txt","rt");
if(fp3 == NULL){
printf("\n打开失败!");
exit(1);
}
fscanf(fp1,"%d %d",&G.vexnum,&G.arcnum); //从文件中顶点的个数和边的个数
printf("\t已读取到顶点个数和边的数目\n");
for(i=1;i<=G.vexnum;i++){
fscanf(fp3,"%s\n%s\n%s\n",name,info,haha);
G.vnodes[i].vex[i].vexNum=i;
strcpy(G.vnodes[i].vex[i].name,name);
strcpy(G.vnodes[i].vex[i].info,info);
strcpy(G.vnodes[i].vex[i].haha,haha);
G.vnodes[i].firstarc=NULL;//初始化
}
printf("\t已读取到各个顶点的信息,并成功初始化各个顶点对应的链表\n");
for(k=1;k<=G.arcnum;k++)//利用循环输入所有边的两个顶点和权值
{
fscanf(fp2,"%10d %10d %10d\n",&v1,&v2,&w);
printf("已读取到第%d条边的两个顶点和权值...\n",k);
i=LocateVex(G,v1);j=LocateVex(G,v2);//定位
p=(ArcNode*)malloc(sizeof(ArcNode));//申请一个结点
p->adjvex=j;
p->weight=w;
p->nextarc=NULL;//赋值
p->nextarc=G.vnodes[i].firstarc;//连接结点
G.vnodes[i].firstarc=p;//连接结点
//逆邻接表
q=(ArcNode*)malloc(sizeof(ArcNode));
q->adjvex=i;
q->weight=w;
q->nextarc=NULL;
q->nextarc=G.vnodes[j].firstarc;
G.vnodes[j].firstarc=q;
}
fclose(fp1);
fclose(fp2);
fclose(fp3);
}
void InputGraph(ALGraph G)//邻接表的输出
{
int i,j;//记录次数
ArcNode *p;//用于遍历链表
printf("邻接表为:\n");
for(i=1;i<=G.vexnum;i++)//利用循环输出
{
printf("%d |%s|",i,G.vnodes[i].vex[i].name);
p = G.vnodes[i].firstarc;
while(p)//当p为空时,结束循环
{
printf(" -[%d]-> %d",p->weight,p->adjvex);
p = p->nextarc;//p指向p的下一个结点
}
printf("\n");
}
}
void printPlace(ALGraph G){
for(int vex=1;vex<=G.vexnum;vex++){
printf("\t\t\t\t%d. %s\n",vex,G.vnodes[vex].vex[vex].name);
}
}
void queryPlace(ALGraph G){
system("cls");
int num,c,i,flag=1;
char n[10];
printPlace(G);
while(flag == 1){
printf("\t\t\t|----------地点信息查询---------------|\n");
printf("\t\t\t| |\n");
printf("\t\t\t| 1. 按照编号查询 |\n");
printf("\t\t\t| 2. 按照名称查询 |\n");
printf("\t\t\t| 3. 按照推荐指数查询 |\n");
printf("\t\t\t| 4. 按照编号和名称同时查询 |\n");
printf("\t\t\t| |\n");
printf("\t\t\t|-------------------------------------|\n\n");
printf("\t\t\t\t\t\t请输入要查看地点的方式:");
scanf("%d",&c);
if(c == 1){
system("cls");
printPlace(G);
printf( "\t\t\t\t\t\t请输入需要查找的地点编号:" );
scanf( "%d", &num );
if(num > 0 && num <= G.vexnum ){
printf( "\n\n");
printf( "\t\t\t编号:%d\n",num);
printf( "\t\t\t名称:%s\n", G.vnodes[num].vex[num].name );
printf( "\t\t\t简介:%s\n\n", G.vnodes[num].vex[num].info );
printf( "\t\t\t推荐指数:%s\n\n", G.vnodes[num].vex[num].haha );
}
else{
printf( "\t\t\t\t\t\t信息输入有误!\n" );
}
printf( "\n\t\t\t\t\t\t是否继续查询地点信息?\n" );
printf( "\t\t\t\t\t\t1:是\n" );
printf( "\t\t\t\t\t\t0:返回管理员菜单菜单:" );
scanf( "%d", &flag );
}
else if(c == 2){
system("cls");
printPlace(G);
printf("\t\t\t\t\t\t请输入需要查询的地点名称:");
scanf("%s",n);
for(i = 1; i <= G.vexnum; i++ ){
if(strcmp(G.vnodes[i].vex[i].name,n) == 0){
printf( "\n\n");
printf( "\t\t\t编号:%d\n",i);
printf( "\t\t\t名称:%s\n", G.vnodes[i].vex[i].name );
printf( "\t\t\t简介:%s\n\n", G.vnodes[i].vex[i].info );
printf( "\t\t\t推荐指数:%s\n\n", G.vnodes[i].vex[i].haha );
break;
}
}
printf( "\n\t\t\t\t\t\t是否继续查询地点信息?\n" );
printf( "\t\t\t\t\t\t1:是\n" );
printf( "\t\t\t\t\t\t0:返回上级菜单:" );
scanf( "%d", &flag );
}
else if(c == 3){
system("cls");
printPlace(G);
printf("\t\t\t\t\t\t请输入需要查询的推荐指数(*~~*****):");
scanf("%s",n);
for(i = 1; i <= G.vexnum; i++ ){
if(strcmp(G.vnodes[i].vex[i].haha,n) == 0){
printf( "\n\n");
printf( "\t\t\t编号:%d\n",i);
printf( "\t\t\t名称:%s\n", G.vnodes[i].vex[i].name );
printf( "\t\t\t简介:%s\n\n", G.vnodes[i].vex[i].info );
printf( "\t\t\t推荐指数:%s\n\n", G.vnodes[i].vex[i].haha );
printf("\t\t\t----------------------------------------\n");
}
}
printf( "\n\t\t\t\t\t\t是否继续查询地点信息?\n" );
printf( "\t\t\t\t\t\t1:是\n" );
printf( "\t\t\t\t\t\t0:返回上级菜单:" );
scanf( "%d", &flag );
}
else if(c == 4){
system("cls");
printPlace(G);
printf( "\t\t\t\t\t\t请输入需要查找的地点编号:" );
scanf( "%d", &num );
printf("\t\t\t\t\t\t请输入需要查询的地点名称:");
scanf("%s",n);
if(num > 0 && num <= G.vexnum && strcmp(G.vnodes[num].vex[num].name,n) == 0){
printf( "\n\n");
printf( "\t\t\t编号:%d\n",num);
printf( "\t\t\t名称:%s\n", G.vnodes[num].vex[num].name );
printf( "\t\t\t简介:%s\n\n", G.vnodes[num].vex[num].info );
printf( "\t\t\t推荐指数:%s\n\n", G.vnodes[num].vex[num].haha );
}else{
printf( "\t\t\t\t\t\t信息输入有误!\n" );
}
printf( "\n\t\t\t\t\t\t是否继续查询地点信息?\n" );
printf( "\t\t\t\t\t\t1:是\n" );
printf( "\t\t\t\t\t\t0:返回上级菜单:" );
scanf( "%d", &flag );
}else{
printf("\n----信息输入有误,重新输入!!!----\n");
}
}
system("cls");
}
void user(){
VNode G;
AdjFile();//邻接表信息,顶点数,边数。每条边上标,下标,权值
addressInfoFile(G);//创建顶点信息,存入文件
ALGraph G1;
Create(G1);//创建邻接表
int x;
while(1){
printf("\n\n\t\t\t|------欢迎您的进入-------\t|\n");
printf("\t\t\t| \t|\n");
printf("\t\t\t| 1. 西邮校园游览图 \t|\n");
printf("\t\t\t| 2. 查询地点信息 \t|\n");
printf("\t\t\t| 3. 查询地点路线 \t|\n");
printf("\t\t\t| 请进行选择,输入0退出: \t|\n");
printf("\t\t\t| \t|\n");
printf("\t\t\t|-------------------------\t|\n");
printf("输入:");
scanf("%d",&x);
switch(x){
case 1: system("cls"); printMap(); break;
case 2: system("cls"); queryPlace(G1); break;
case 3: system("cls"); queryPath(G1); break;
case 0: printf("\n\t\t\t\t\t\t\t"); exit(0); break;
default: printf("\n———————————————输入信息错误,请重新输入!!!————————————————————\n"); break;
}
}
}
int insertArc(ALGraph *g,int pa,int pb,int aweight)
{
ArcNode*p;
if(pa<0||pb<0)
{
printf("这个边并不存在,请重新输入\n");
return 0;
}
p=(ArcNode*)malloc(sizeof(ArcNode));
p->adjvex=pb;
p->weight=aweight;
//下面把这个边信息插到起点的弧信息的第一个
p->nextarc=g->vnodes[pa].firstarc;
g->vnodes[pa].firstarc=p;
g->arcnum++;//边个数增加
return 1;
}
int insertVex(ALGraph *g,VexInfo newvex)
{
g->vnodes[newvex.vexNum].vex[newvex.vexNum].vexNum=newvex.vexNum;
strcpy(g->vnodes[newvex.vexNum].vex[newvex.vexNum].name,newvex.name);
strcpy(g->vnodes[newvex.vexNum].vex[newvex.vexNum].info,newvex.info);
strcpy(g->vnodes[newvex.vexNum].vex[newvex.vexNum].haha,newvex.haha);
g->vnodes[newvex.vexNum].firstarc=NULL;
g->vexnum++;//顶点个数增加
return g->vexnum;
}
void addPlace(ALGraph *g){
VexInfo newvex;
char name[30]; //名称
char info[70]; //介绍
char haha[10]; //推荐指数
int pb,pa,weight;
printf("\t\t\t---- 请编辑添加地点的信息----");
printf("\n\t\t\t 1.输入地点名称:");
scanf("%s",name);
printf("\n\t\t\t 2.输入地点简介:");
scanf("%s",info);
printf("\n\t\t\t 3.输入地点推荐指数(*~~*****):");
scanf("%s",haha);
newvex.vexNum=g->vexnum+1;
strcpy(newvex.name,name);
strcpy(newvex.info,info);
strcpy(newvex.haha,haha);
if(insertVex(g,newvex)){
printf("\n\n\t\t\t地点|%d.%s|添加成功!!!\n\n",g->vexnum,name);
}
printPlace(*g);
int flag = 1;
while(flag == 1){
pa=g->vexnum;
printf("\n\t\t\t---- 请编辑添加的地点的路径信息----");
printf("\n\n\t\t 1.输入与|%d.%s|相连的地点编号:",g->vexnum,name);
scanf("%d",&pb);
eatline();
printf("\n\t\t 2.输入此路径|%d.%s|-[???]->|%d.%s|的权值:",g->vexnum,g->vnodes[pa].vex[pa].name,g->vnodes[pb].vex[pb].vexNum,g->vnodes[pb].vex[pb].name);
scanf("%d",&weight);
if(insertArc(g,pa,pb,weight)){
printf("\n\t\t\t添加成功,|%s|-[%d]->|%s|\n\n\n",g->vnodes[pa].vex[pa].name,weight,g->vnodes[pb].vex[pb].name);
}
printf("\t\t\t\t 输入0退回上级菜单,输入1继续添加, 输入2查看此时邻接表:" );
scanf("%d", &flag);
if(flag==2){
InputGraph(*g);
}
}
}
int DeleteArc(ALGraph *g,int pa,int pb)
{
ArcNode *p,*temp;
if(pa<0||pb<0)
return 0;
p=g->vnodes[pa].firstarc;
if(p->adjvex==pb)//p为头结点的情况
{
temp=p;
free(temp);
g->vnodes[pa].firstarc=p->nextarc;
}
while(p->nextarc!=NULL)
{
if(p->nextarc->adjvex==pb)
{
temp=p->nextarc;
p->nextarc=temp->nextarc;
free(temp);
break;
}
p=p->nextarc;
}
g->arcnum--;//边个数减一
return 1;
}
int Delete(ArcNode *p)//删除顶点的辅助函数:递归调用删除弧结点内容
{
if(p)
{
Delete(p->nextarc);
free(p);
return 1;
}
else
return NULL;
}
int DeleteVex(ALGraph *g,int pdata)
{
int qq=0;
ArcNode *p,*del,*pre;
if(pdata<0)//结点不存在,返回错误信息
return 0;
//Delete(g->vertexs[pdata].firstarc);//删除这个结点储存的弧信息
p=g->vnodes[pdata].firstarc;
while(p)
{
g->arcnum--;
p=p->nextarc;
}
int i;
for(i=pdata;i<g->vexnum-1;i++)//数组内容移位
{
g->vnodes[i].vex[i]=g->vnodes[i+1].vex[i+1];
g->vnodes[i].firstarc=g->vnodes[i+1].firstarc;//顶点信息和第一条弧的指针都移位
}
g->vnodes[g->vexnum-1].vex[i].vexNum=-1;
g->vnodes[g->vexnum-1].firstarc=NULL;
g->vexnum--;//顶点个数减1
for(i=0;i<g->vexnum;i++)
{
p=g->vnodes[i].firstarc;
while(p)
{
if(p->adjvex==pdata)
{
if(p==g->vnodes[i].firstarc)
{
del=p;
p=p->nextarc;
g->vnodes[i].firstarc=p;
pre=NULL;
free(del);
g->arcnum--;
break;
}
else
{
del=p;
p=p->nextarc;
pre->nextarc=p;
free(del);
g->arcnum--;
break;
}
}
else if(p->adjvex>pdata)
{
p->adjvex--;
}
pre=p;
p=p->nextarc;
}
}
return 1;
}
void adminMenu(){
VNode G;
AdjFile();//邻接表信息,顶点数,边数。每条边上标,下标,权值
addressInfoFile(G);//创建顶点信息,存入文件
ALGraph G1;
Create(G1);//创建邻接表
system("cls");
FILE* fp;
char name[30];
char n[8];
if ((fp = fopen("regist.txt", "r")) == NULL) {
printf("文件打开失败");
exit(1);
}
fscanf(fp, "%s\t%s\n", name, n);
fclose(fp);
printf("\t\t\t欢迎您管理员[%s]\n\n",name);
int c;
int x;
while(1){
system("\n\n\n\n\n");
printf("\t\t\t [%s] \n",name);
printf("\t\t\t|--------------------------------------|\n");
printf("\t\t\t| |\n");
printf("\t\t\t| 1. 添加新地点 |\n");
printf("\t\t\t| 2. 添加新路线 |\n");
printf("\t\t\t| 3. 删除旧路线 |\n");
printf("\t\t\t| 4. 删除旧地点 |\n");
printf("\t\t\t| 5. 西邮校园游览图 |\n");
printf("\t\t\t| 6. 查询地点信息 |\n");
printf("\t\t\t| 7. 查询地点路线 |\n");
printf("\t\t\t| 8. 查看邻接表 |\n");
printf("\t\t\t| 请选择您需要的操作,输入0退出: |\n");
printf("\t\t\t| |\n");
printf("\t\t\t|--------------------------------------|\n");
printf("输入:");
scanf("%d",&c);
getchar();
switch(c){
case 1: system("cls"); addPlace(&G1); break;
case 2: system("cls");
printPlace(G1);
int pb,weight,pa;
printf("\n\n\t\t 1.输入第一个地点的编号:");
scanf("%d",&pa);
printf("\n\n\t\t 2.输入第二个地点的编号:");
scanf("%d",&pb);
printf("\n\n\t\t 3.输入此路径的权值:");
scanf("%d",&weight);
if(insertArc(&G1,pa,pb,weight)){
printf("\n\t路径添加成功!!!\n\n");
} break;
case 3: system("cls");
InputGraph(G1);
int pb1,pa1;
printf("\n\n\t\t 1.输入第一个地点的编号:");
scanf("%d",&pa1);
printf("\n\n\t\t 2.输入第二个地点的编号:");
scanf("%d",&pb1);
if(DeleteArc(&G1,pa1,pb1)){
printf("\n\t路径删除成功!!!\n\n");
} break;
case 4: system("cls");
int pb2;
printf("\n\n\t\t 输入删除地点的编号:");
scanf("%d",&pb2);
DeleteVex(&G1,pb2);
break;
case 5: system("cls"); printMap(); break;
case 6: system("cls"); queryPlace(G1); break;
case 7: system("cls"); queryPath(G1); break;
case 8: system("cls"); InputGraph(G1);break;
case 0: printf("\n\t\t\t\t\t\t\t"); exit(0);
default: printf("\n———————————————输入信息错误,请重新输入!!!————————————————————\n"); break;
}
}
}
//管理员
void admin(){
int x;
while(1){
printf("|------------------------------------------------校园导游系统------------------------------------------------------|\n");
printf("|--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*---|\n");
printf("| |\n");
printf("| ----------- ------------- |\n");
printf("| |1.登录 | |2.注册 | |\n");
printf("| ----------- ------------- |\n");
printf("| |\n");
printf("|--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*---|\n");
printf("|--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*---|\n");
printf("请选择序号:");
//sysytem("cls") 功能是清屏
while(1){
scanf("%d",&x);
switch(x){
case 1: system("cls"); login(); break;
case 2: system("cls"); regist(); break;
default: printf("\n———————————————输入无效,请重新正确输入!!!————————————————————\n"); break;
}
}
}
}
main(){
int flag;
system("color 70");
printf("|------------------------------------------------校园导游系统------------------------------------------------------|\n");
printf("|--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*---|\n");
printf("| |\n");
printf("| ----------- ------------- |\n");
printf("| |1.用户 | |2.管理员 | |\n");
printf("| ----------- ------------- |\n");
printf("| |\n");
printf("|--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*---|\n");
printf("|--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*---|\n");
printf("请选择序号:");
//sysytem("cls") 功能是清屏
while(1){
printf("请选择序号:");
scanf("%d",&flag);
switch(flag){
case 1: system("cls"); user(); break;
case 2: system("cls"); admin(); break;
default: printf("\n———————————————输入无效,请重新正确输入!!!————————————————————\n"); break;
}
}
}
//注册
void regist(){
FILE* fp;
char name[30];
char n[8],n1[8];
while (1) {
system("cls");
printf("请输入要创建的用户名:");
scanf("%s", name);
eatline();
printf("请输入密码(仅限六位数字,不允许使用符号):");
scanf("%s", n);
eatline();
printf("请确认密码(务必输入六位):");
scanf("%s", n1);
eatline();
if (strcmp(n ,n1) == 0) {
if ((fp = fopen("regist.txt", "w+")) == NULL) {
printf("文件打开失败");
exit(1);
}
for (int n2 = 0; n2 < 6; n2++) {
*(n + n2) += 3;
}
fprintf(fp, "%s\t%s\n", name, n);
fclose(fp);
printf("\n用户创建成功...\n\n");
login();
}
else {
printf("两次密码输入不同,请重新设定密码!\n");
}
}
}
//登录
void login(){
system("cls");
FILE* fp;
int i = 5;
char n1[8];
char name1[30];
if ((fp = fopen("regist.txt", "r+")) == NULL) {
printf("文件打开失败");
exit(1);
}
else {
int t = 0;
printf("如需注册请输入1,否则输入0\n");
printf("请输入:");
scanf("%d", &t);
if (t == 1) {
regist();
}
char n2[8];
char name2[30];
fscanf(fp, "%s\t%s\n", name2, n2);
//执行加密
for (int n3 = 0; n3 < 6; n3++) {
*(n2 + n3) -= 3;
}
printf("请输入用户名:");
scanf("%s", name1);
if (strcmp(name2, name1) == 0) {
while (1) {
printf("请输入密码:");
scanf("%s", n1);
if (strcmp(n2, n1) != 0) {
i--;
printf("\n密码错误,还可尝试%d次\n", i);
}
else {
printf("\n输入正确,进入系统...\n\n");
adminMenu();
eatline();
break;
}
if (i == 0) {
printf("错误次数过多,系统退出\n");
exit(0);
}
}
}else{
printf("无此用户名!!!程序崩溃(-_-)!!!\n");
}
}
fclose(fp);
}
学习参考博客:
数据结构 c语言 Dijkstra算法寻找最短路径 邻接表实现
校园导游系统(C语言、图、文件存储)
药店管理系统(c语言链表实现)
c语言数据从链表写入到文件和从文件读取到链表
【图】【邻接表】【DFS】求两个顶点间所有路径
数据结构 c语言 有向图和无向图邻接表的建立、插入、和删除操作
无向图 邻接表的创建 - C语言
图的邻接表存储—C语言
2020/12/30/16:10