首页 > 其他分享 >校园导航图(C语言)

校园导航图(C语言)

时间:2024-07-26 11:25:15浏览次数:11  
标签:vexnum AdjMatrix int 校园 C语言 ++ printf 导航 getchar

功能分析

主要实现了一个校园导航图的相关功能,具体分析如下:

  1. 图的数据结构定义
    • AdjMatrix结构体定义了图的邻接矩阵、地点名称、地点介绍、地点个数和路线个数等信息。
  2. 功能函数
    • WriteFileAdjMatrix:将邻接矩阵写入文件。
    • delOldAddress:删除旧地点。
    • delOldPath:删除指定路线。
    • addNewAddressPath:增加新的地点和路径。
    • displayAddressInfo:显示指定地点的信息。
    • displaySimplePath:显示指定两地的简单路径。
    • displayShortestPath:显示指定两地的最短路线。
    • prime:计算最佳布网路线。
    • printPath:打印所有路线。
    • ReadFileCreateAdjMatrix:从文件中读取数据创建邻接矩阵。
    • bestNetworkPath:获取最佳布网方案。
    • onlyAddNewPath:添加新路线或修改路线长度。
    • menu:提供用户操作界面,根据用户选择执行不同功能。
    • getVexNo:通过顶点名称返回顶点序号。
    • Create:创建新的路线图。
    • printAdjMatrix:打印邻接矩阵。
  3. 主函数
    • 从文件中读取数据创建邻接矩阵。
    • 调用menu函数进入用户操作界面。

源码

#include<stdio.h>
#include<stdlib.h>
#include<string.h>

#define MAXVEX 30
#define INFINITY 32768
typedef struct {                     //定义图的数据类型
	int arcs[MAXVEX][MAXVEX];
	char vex[MAXVEX][30];               //地点名称
	char info[MAXVEX][100];            //地点介绍
	int vexnum;                         //地点个数
	int arcnum;                         //路线个数
}AdjMatrix;

int visit[MAXVEX] = { 0 };

void WriteFileAdjMatrix(AdjMatrix *);          //将邻接矩阵写入文件
void delOldAddress(AdjMatrix *);                //删除旧地点
void delOldPath(AdjMatrix *);                  //删除指定路线
void addNewAddressPath(AdjMatrix *);            //增加新的地点和路径
void displayAddressInfo(AdjMatrix *);           //显示指定地点的信息
void displaySimplePath(AdjMatrix *);            //显示指定两地的简单路径
void displayShortestPath(AdjMatrix *);          //显示指定两地的最短路线


typedef struct {
	int num[MAXVEX];
	int top;
}Stack;

void in(Stack * S, int num) {
	S->top++;
	S->num[S->top] = num;
}

void out(Stack * S, int * num) {
	*num = S->num[S->top];
	S->top--;
}

void gettop(Stack * S, int * num) {
	*num = S->num[S->top];
}

int isEmpty(Stack * S) {
	if (S->top != -1) {
		return 0;
	}
	else {
		return 1;
	}
}

void showman()
{
	FILE *fp;
	char ch;
	system("cls");
	fp = fopen("man.txt", "r");
	while (!feof(fp))
	{
		ch = fgetc(fp);
		putchar(ch);
	}
	printf("\b 任意键返回……");
	getchar();
	getchar();
}
int getVexNo(AdjMatrix * G, char * str)         //通过顶点的名称返回该顶点的序号
{
	int i;
	for (i = 1; i <= G->vexnum; i++) {
		if (!strcmp(G->vex[i], str)) {
			return i;
		}
	}
	return -1;
}

void Create(AdjMatrix * G)
{
	int i, j, distance, vex1, vex2, arcnum = 0;
	printf("请输入地点的个数:\n");
	scanf(" %d", &G->vexnum);
	for (i = 1; i <= G->vexnum; i++) {            //将邻接矩阵初始化为所有边为最大距离
		for (j = 1; j <= G->vexnum; j++) {
			G->arcs[i][j] = INFINITY;
		}
	}
	printf("请输入%d个地点:\n", G->vexnum);
	for (i = 1; i <= G->vexnum; i++) {
		printf("第%d个地点:", i);
		scanf(" %s", G->vex[i]);
		printf("请输入该地点的介绍:");
		scanf(" %s", G->info[i]);
	}
	printf("请输入所有路线,比如宿舍 食堂代表宿舍到食堂的路线,输入0 0结束输入:");
	while (1) {
		char add1[30], add2[30];
		printf("请输入路线:");
		scanf("%s %s", add1, add2);
		if (!strcmp(add1, "0") || !strcmp(add2, "0")) {
			break;
		}
		vex1 = getVexNo(G, add1);
		vex2 = getVexNo(G, add2);
		if (vex1 == -1 || vex2 == -1) {
			printf("此地点不存在!请重新输入!!!");
			continue;
		}
		printf("请输入%s到%s的距离:", add1, add2);
		scanf(" %d", &distance);
		G->arcs[vex1][vex2] = distance;
		G->arcs[vex2][vex1] = distance;
		arcnum++;
	}
	G->arcnum = arcnum;
	WriteFileAdjMatrix(G);
}

void printAdjMatrix(AdjMatrix * G)
{
	int i, j;
	printf("\nAdjMatrix:\n");
	printf("     ");
	for (i = 1; i <= G->vexnum; i++) {
		printf("%5s", G->vex[i]);
	}
	printf("\n");
	for (i = 1; i <= G->vexnum; i++) {
		printf("%-15s", G->vex[i]);
		for (j = 1; j <= G->vexnum; j++) {
			if (G->arcs[i][j] == INFINITY) {
				printf(" ----");
			}
			else {
				printf("%5d", G->arcs[i][j]);
			}
		}
		printf("\n");
	}
	getchar();
}

void prime(AdjMatrix * G, int start)
{
	struct {
		int adjvex;
		int lowcost;
	}closedge[MAXVEX];
	struct {
		char vex1[30];
		char vex2[30];
		int distance;
	}primeTree[MAXVEX];
	int i, e, k, m, min;
	closedge[start].lowcost = 0;
	for (i = 1; i <= G->vexnum; i++) {
		if (i != start) {
			closedge[i].adjvex = start;
			closedge[i].lowcost = G->arcs[start][i];
		}
	}
	for (e = 1; e <= G->vexnum; e++) {
		min = INFINITY;
		for (k = 1; k <= G->vexnum; k++) {
			if (closedge[k].lowcost != 0 && closedge[k].lowcost < min) {
				m = k;
				min = closedge[k].lowcost;
			}
		}
		strcpy(primeTree[e].vex1, G->vex[closedge[m].adjvex]);
		strcpy(primeTree[e].vex2, G->vex[m]);
		primeTree[e].distance = min;
		closedge[m].lowcost = 0;
		for (i = 1; i <= G->vexnum; i++) {
			if (i != m && G->arcs[m][i] < closedge[i].lowcost) {
				closedge[i].lowcost = G->arcs[m][i];
				closedge[i].adjvex = m;
			}
		}
	}
	printf("最佳布网路线如下:\n");
	for (i = 1; i <= G->vexnum - 1; i++) {
		printf("%s-->%s 距离:%d\n", primeTree[i].vex1, primeTree[i].vex2, primeTree[i].distance);
	}
}

void printPath(AdjMatrix * G)
{
	system("cls");
	int i, j;
	for (i = 1; i <= G->vexnum; i++) {
		for (j = 1; j <= G->vexnum; j++) {
			if (G->arcs[i][j] != INFINITY) {
				printf("%s-->%s 距离:%d     ", G->vex[i], G->vex[j], G->arcs[i][j]);
			}
		}
		printf("\n");
	}
	getchar();
	getchar();
}

void ReadFileCreateAdjMatrix(AdjMatrix * G)         //从文件中读取数据创建邻接矩阵
{
	FILE * fp = fopen("AdjMatrix.txt", "r");
	if (fp == NULL) {
		printf("文件访问出错\n");
		exit(0);
	}
	fread(G, sizeof(AdjMatrix), 1, fp);
	fclose(fp);
}

void WriteFileAdjMatrix(AdjMatrix * G)
{
	FILE * fp = fopen("AdjMatrix.txt", "w");
	if (fp == NULL) {
		printf("文件访问出错,任意键返回……");
		getchar();
		getchar();
		return;
	}
	fwrite(G, sizeof(AdjMatrix), 1, fp);
	fclose(fp);
}

void bestNetworkPath(AdjMatrix * G)
{
	system("cls");
	char str[30];
	int num;
	printf("请输入布网起点:");
	scanf(" %s", str);
	num = getVexNo(G, str);
	if (num == -1) {
		printf("该地点不存在!任意键返回……");
		getchar();
		getchar();
		return;
	}
	else {
		prime(G, num);
	}
	getchar();
	getchar();
}

void onlyAddNewPath(AdjMatrix * G)
{
	system("cls");
	int distance, num1, num2;
	char str1[30], str2[30];
	printf("请输入路径的起点和终点:");
	scanf(" %s %s", str1, str2);
	num1 = getVexNo(G, str1);
	num2 = getVexNo(G, str2);
	if (num1 == -1 || num2 == -1) {
		printf("该地点不存在!任意键返回……");
		getchar();
		getchar();
		return;
	}
	printf("请输入%s到%s的距离:", str1, str2);
	scanf(" %d", &distance);
	G->arcs[num1][num2] = distance;
	WriteFileAdjMatrix(G);
	printf("添加/修改成功,任意键返回……");
	getchar();
	getchar();
}

void menu(AdjMatrix * G)
{
	int select;
	while (1) {
		system("cls");
		printf("\n\n\t\t\t\t校园导航图\n");
		printf("\t\t\t*************************\n");
		printf("\t\t\t1.创建新的路线图\n");
		printf("\t\t\t2.显示指定地点的信息\n");
		printf("\t\t\t3.显示指定两地的简单路径\n");
		printf("\t\t\t4.显示指定两地的最短路线\n");
		printf("\t\t\t5.增加新的地点和路线\n");
		printf("\t\t\t6.删除旧地点\n");
		printf("\t\t\t7.删除指定路线\n");
		printf("\t\t\t8.显示所有的路线\n");
		printf("\t\t\t9.最佳布网方案\n");
		printf("\t\t\t10.显示平面图\n");
		printf("\t\t\t11.添加新路线或修改路线长度\n");
		printf("\t\t\t0.退出\n");
		printf("\t\t\t*************************\n");
		printf("\t\t\t  请选择:");
		scanf(" %d", &select);
		switch (select) {
		case 1:
			Create(G);
			break;
		case 2:
			displayAddressInfo(G);
			break;
		case 3:
			displaySimplePath(G);
			break;
		case 4:
			displayShortestPath(G);
			break;
		case 5:
			addNewAddressPath(G);
			break;
		case 6:
			delOldAddress(G);
			break;
		case 7:
			delOldPath(G);
			break;
		case 8:
			printPath(G);
			break;
		case 9:
			bestNetworkPath(G);
			break;
		case 10:
			showman();
			break;
		case 11:
			onlyAddNewPath(G);
			break;
		case 0:
			exit(0);
		default:
			continue;
		}
	}
}

void displayAddressInfo(AdjMatrix * G)
{
	system("cls");
	int num;
	char str[30];
	printf("请输入要显示信息的地点名:");
	scanf(" %s", str);
	num = getVexNo(G, str);
	if (num == -1) {
		printf("该地点不存在!");
	}
	else {
		printf("%s 简介:%s\n", G->vex[num], G->info[num]);
	}
	getchar();
	getchar();
}

int gettopnextAdj(AdjMatrix * G, int top, int st)        //取当前栈顶的 下一个 邻接点,上一个邻接点是退栈前的栈定
{
	int i;
	for (i = st + 1; i <= G->vexnum; i++) {
		if (G->arcs[top][i] != INFINITY) {
			return i;
		}
		else {
			continue;
		}
	}
	return 0;
}

void displaySimplePath(AdjMatrix * G)
{
	system("cls");
	char str1[30], str2[30];
	int start, end, st = 0, top, i;
	int count = INFINITY;
	int mindist[MAXVEX];
	Stack * S;
	S = (Stack *)malloc(sizeof(Stack));
	S->top = -1;
	printf("请输入起点和终点,中间用空格隔开:");
	scanf(" %s %s", str1, str2);
	start = getVexNo(G, str1);
	end = getVexNo(G, str2);
	if (start == -1 || end == -1) {
		printf("该地点不存在,任意键返回……");
		getchar();
		getchar();
		return;
	}
	in(S, start);
	visit[start] = 1;
	printf("\n\n%s到%s的简单路径如下:\n", str1, str2);
	while (!isEmpty(S)) {
		gettop(S, &top);
		st = gettopnextAdj(G, top, st);
		if (st == 0) {
			out(S, &st);
			visit[st] = 0;
		}
		else if (st != 0 && visit[st] == 0) {
			in(S, st);
			visit[st] = 1;
			if (st == end) {
				if (count > S->top + 1) {
					count = S->top + 1;
					for (i = 0; i < count; i++) {
						mindist[i] = S->num[i];
					}
				}
				printf("%s", G->vex[S->num[0]]);
				for (i = 1; i <= S->top; i++) {
					printf("-->%s", G->vex[S->num[i]]);
				}
				printf("\n");
			}
		}
	}
	printf("\n\n中转次数最少的路径如下:\n");
	for (i = 0; i < count; i++) {
		if (i == 0) {
			printf("%s", G->vex[mindist[i]]);
		}
		else {
			printf("-->%s", G->vex[mindist[i]]);
		}
	}
	printf("\n\n");
	getchar();
	getchar();
}

void Dijkstra(AdjMatrix * G, int start, int dist[], int path[][MAXVEX])         //求起点到所有点的最短路径
{
	int mindist, i, j, k, t = 1;
	for (i = 1; i <= G->vexnum; i++) {
		dist[i] = G->arcs[start][i];
		if (G->arcs[start][i] != INFINITY) {
			path[i][1] = start;
		}
	}

	for (i = 2; i <= G->vexnum; i++) {
		mindist = INFINITY;
		for (j = 1; j <= G->vexnum; j++) {
			if (!path[j][0] && dist[j] < mindist) {
				k = j;
				mindist = dist[j];
			}
		}
		if (mindist == INFINITY) {
			return;
		}
		path[k][0] = 1;
		for (j = 1; j <= G->vexnum; j++) {
			if (!path[j][0] && G->arcs[k][j] < INFINITY && dist[k] + G->arcs[k][j] < dist[j]) {
				dist[j] = dist[k] + G->arcs[k][j];
				t = 1;
				while (path[k][t] != 0) {
					path[j][t] = path[k][t];
					t++;
				}
				path[j][t] = k;
				path[j][t + 1] = 0;
			}
		}
	}
}

void displayShortestPath(AdjMatrix * G)                 //显示两地之间最短路径
{
	system("cls");
	char str1[30], str2[30];
	int start, end, dist[MAXVEX], i = 1;
	printf("请输入起点和终点,中间用空格隔开:");
	scanf(" %s %s", str1, str2);
	start = getVexNo(G, str1);
	end = getVexNo(G, str2);
	if (start == -1 || end == -1) {
		printf("该地点不存在!任意键返回……");
		getchar();
		getchar();
		return;
	}
	int path[MAXVEX][MAXVEX] = { 0 };
	Dijkstra(G, start, dist, path);
	while (path[end][i]) {
		printf("%s-->", G->vex[path[end][i]]);
		i++;
	}
	printf("%s\n", G->vex[end]);
	getchar();
	getchar();
}

void addNewAddressPath(AdjMatrix * G)
{
	char str[30];
	int vexnum;
	int num1, i;
	int distance;
	printf("请输入地点名:");
	scanf(" %s", str);
	vexnum = G->vexnum;
	G->vexnum++;
	printf("请输入地点的介绍:");
	scanf(" %s", G->info[G->vexnum]);
	vexnum++;
	strcpy(G->vex[vexnum], str);
	for (i = 1; i <= G->vexnum; i++) {
		G->arcs[vexnum][i] = INFINITY;
		G->arcs[i][vexnum] = INFINITY;
	}
	printf("请输入与该地点有路径的地点和它们之间的距离(中间用空格隔开,0 0 代表结束输入):\n");
	while (1) {
		scanf(" %s %d", str, &distance);
		if (!strcmp(str, "0")) {
			break;
		}
		num1 = getVexNo(G, str);
		if (num1 == -1) {
			printf("该地点不存在!按任意键返回……");
			getchar();
			getchar();
			return;
		}
		else {
			G->arcs[vexnum][num1] = distance;
			G->arcs[num1][vexnum] = distance;
		}
	}
	WriteFileAdjMatrix(G);
}

void delOldAddress(AdjMatrix * G)
{
	char str[30];
	printf("输入要删除的地点:");
	scanf(" %s", str);
	int num;
	num = getVexNo(G, str);
	if (num == -1) {
		printf("该地点不存在!!任意键返回……");
		getchar();
		getchar();
		return;
	}
	int i, j;
	for (i = num; i <= G->vexnum - 1; i++) {
		strcpy(G->vex[i], G->vex[i + 1]);
		strcpy(G->info[i], G->info[i + 1]);
	}

	for (i = num; i <= G->vexnum - 1; i++) {
		for (j = 1; j <= G->vexnum; j++) {
			G->arcs[i][j] = G->arcs[i + 1][j];
		}
	}
	for (j = num; j <= G->vexnum - 1; j++) {
		for (i = 1; i <= G->vexnum - 1; i++) {
			G->arcs[i][j] = G->arcs[i][j + 1];
		}
	}
	G->vexnum--;
}

void delOldPath(AdjMatrix * G)
{
	system("cls");
	char str1[30], str2[30];
	int num1, num2;
	printf("请输入路径的起点和终点用空格隔开:");
	scanf(" %s %s", str1, str2);
	num1 = getVexNo(G, str1);
	num2 = getVexNo(G, str2);
	if (num1 == -1) {
		printf("起点不存在!任意键返回……");
		getchar();
		getchar();
		return;
	}
	else if (num2 == -1) {
		printf("终点不存在!任意键返回……");
		getchar();
		getchar();
		return;
	}
	else if (G->arcs[num1][num2] == INFINITY) {
		printf("该路径不存在!任意键返回");
		getchar();
		getchar();
		return;
	}
	else {
		G->arcs[num1][num2] = INFINITY;
	}
	return;
}

int main(void)
{
	AdjMatrix * G;
	G = (AdjMatrix *)malloc(sizeof(AdjMatrix));
	ReadFileCreateAdjMatrix(G);
	menu(G);
}

标签:vexnum,AdjMatrix,int,校园,C语言,++,printf,导航,getchar
From: https://blog.csdn.net/zeyeqianli/article/details/140710847

相关文章

  • C语言 —— 数组
    目录1.数组的概念2.一维数组2.1一维数组的创建2.2一维数组的初始化2.3一维数组的使用3.二维数组3.1二维数组的创建3.2二维数组的初始化3.2.1不完全初始化3.2.2完全初始化3.2.3按照行初始化3.2.4初始化可以省略行,但不能省略列3.3二维数组的使用1.数......
  • E19.【C语言】练习:数组
    有序序列合并描述输入两个升序排列的序列,将两个序列合并为一个有序序列并输出。数据范围:1≤n,m≤1000 ,序列中的值满足0≤val≤30000输入描述:输入包含三行,第一行包含两个正整数n,m,用空格分隔。n表示第二行第一个升序序列中数字的个数,m表示第三行第二个升序序列中数......
  • 34.【C语言之外】聊聊CE扫雷(XP版)作弊
    1.载入扫雷进程2.选9*9扫雷搜素左上角第一个雷的地址先:之后:与灵活切换  3.结果 格子的坐标(x,y):以下全是基址(1,1)~(9,1):对应01005361~01005369(1,2)~(9,2):对应01005381~01005389(1,3)~(9,3):对应010053A1~010053A9发现:01005381-01005361==010053A1-01005381=20(HEX),偏移量......
  • C语言day01
    C语言day01Linux终端窗口提示语句:hq@ubuntu:~$用户名间隔符主机名间隔符当前路径输入提示符间隔符一般都是一些符号,但也有少数符号不是间隔符,比如~表示当前路径特殊符号:~:家目录权限最高/:根目录-:上一次操作的路径.:当前目录..:上一级目录Linux命令......
  • 基于SpringBoot+Vue+uniapp的校园二手书交易平台(源码+lw+部署文档+讲解等)
    文章目录前言详细视频演示具体实现截图技术栈后端框架SpringBoot前端框架Vue持久层框架MyBaitsPlus系统测试系统测试目的系统功能测试系统测试结论为什么选择我代码参考数据库参考源码获取前言......
  • 整理的比较全面的C语言入门笔记!
    c语音在线教程:54笨鸟C语言一经出现就以其功能丰富、表达能力强、灵活方便、应用面广等特点迅速在全世界普及和推广。C语言不但执行效率高而且可移植性好,可以用来开发应用软件、驱动、操作系统等。C语言也是其它众多高级语言的鼻祖语言,所以说学习C语言是进入编程世界的必修课。......
  • c语言基础学习
    1.求1—1000的完数#include<stdio.h>#include<string.h>intmain(intargc,constchar*argv[]){ for(inti=1;i<1000;i++)//被模数 { intsum=0; for(intj=1;j<i;j++)//模数 { if(i%j==0)//求因子 { sum+=j;//因子和 } } if(s......
  • C语言:字符串函数族strlen,strcmp,C语言实现,
    1.字符串的复制:#include<stdio.h>#include<string.h>intmain(intargc,constchar*argv[]){ chararr[20]={0}; charbrr[20]={0}; intlen; inti; printf("请输入目标字符串arr:\n"); gets(arr); printf("请输入源字符串:\n"); gets(brr......
  • 指针!!C语言(第二篇)
    目录一.数组名的理解二.一维数组传参的本质三.冒泡排序法四.二级指针与指针数组五.字符指针变量与数组指针一.数组名的理解在我们对指针有了初步的理解之外,今天我们来掌握一些新的知识就是数组与指针,第一个对数组名的了解,我们先来看一段代码:intmain(){ int......
  • C语言初阶(4)
    1.C语言中函数的定义在计算机科学中,子程序(英语:Subroutine,procedure,function,routine,method,subprogram,callableunit),是一个大型程序中的某部分代码,由一个或多个语句块组成。它负责完成某项特定任务,而且相较于其他代码,具备相对的独立性。一般会有输入参数并有返......