数据结构课设+校园导航系统+西安邮电大学

数据结构课设+校园导航系统+西安邮电大学

设计目的:在校园建设不断完善的现在,为在校学生提供合适的行走路径,为来访的客人提供各种服务的信息;对于这些问题,可用图结构来表示校园交通网络,编写程序完成校园导游系统。

设计内容: 提供用户以及管理员功能,用户可以对校园地点进行查询,而管理员可以对交通图进行增删查改,同时管理员可以登陆、修改密码等待操作,有一定的交互界面。

校园导游图涉及了地点和道路两方面信息,地点信息以及道路信息应存储在文件中,文件的存储格式自己设计。对这两方面进行查找、增加、修改、删除等操作,并同步更新文件。

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

你可能感兴趣的:(链表,c语言)