数据结构之队列的应用-超好玩的汽车加油站模拟器

数据结构之队列的应用-超好玩的汽车加油站模拟器,第1张

----------------------✨🎉🎈==!!!热烈欢迎各位大佬!!!==🎈🎉✨---------------------

🍹作者: BooleanChar12

✨博客主页: BooleanChar12的博客

💘很喜欢的一句话: Because we all stand on the shoulders of giants.

🥂如有bug和疑惑欢迎大家与我🤺

😍觉得博主文章写的不错的话,希望大家三连(🎉关注,🎉点赞,🎉评论),多多支持一下!!

--------------------------------------------------------------------------🍻==专栏回顾==🍻-------------------------------------------------------------------------------

☕Java(从入门到放弃)🍉数据结构(从放弃到入门)🍒Android开发(从入门到入土)
🍇计算机组成原理(从1到0)🍑计算机网络(从上网到退网)🥝 *** 作系统(从0到0.1)
🍎C语言练习题🏆Leetcode(狂刷笔记)🌺微信小程序开发日记

1.文章概要📕:

🧡💛💚本篇文章带你实现超好玩的汽车加油站模拟器,带你体验一次指挥车辆🚗的感觉!🧡💛💚

2.设计思路💡:
  1. 三个队列(入口队列[3],加油队列[3],出口队列[3]) 3指每个队列最大容纳3辆车,由于使用循环队列,并且是空一位来判断队列是否满,所以实际队列大小为4
  2. 提供三个主要 *** 作供加油站指挥人员选择(指挥用户进入加油站,指挥加油,指挥用户驶出加油站)(具体思路已经写在注释中)
3.重点难点🌈:
  1. 队列的结构体中包含的是一个Car类型的指针
  2. Car结构体中包含的是一个存放车牌的字符数组
  3. 三个主要 *** 作的实现,尤其是指挥加油 *** 作(if的多层嵌套,一定要思路清晰)
4.效果展示🎬:



5.代码实现💎:
# include 
# include 
/*
设计思路:
1.三个队列(入口队列[3],加油队列[3],出口队列[3])  3指每个队列最大容纳3辆车,
  由于使用循环队列,并且是空一位来判断队列是否满,所以实际队列大小为4
2.提供三个主要 *** 作供加油站指挥人员选择(指挥用户进入加油站,指挥加油,指挥用户驶出加油站)
*/


//定义Car结构体
typedef struct {
	char carName[20];//车牌号码   如琼BQQ666  晋AQB888
} Car;

//定义队列结构体
typedef struct {
	Car * base;//指向动态分配内存的首地址,且只能指向Car类型的结构体地址
	int front;//头指针
	int rear;//尾指针
} SqQueue;

//1.队列初始化
int InitQueue(SqQueue &Q) {
	Q.base = (Car *)malloc(4*sizeof(Car));//动态创建连续的内存空间并将此内存空间的首地址赋给Q队列的base指针,即Q队列的base指针指向了这块连续的内存空间
	if(!Q.base) { //判断能不能在内存中找到这样一块连续空间,没有找到就返回-1
		printf("内存溢出,无法开辟空间!");
		return -1;
	}
	//如果找到了,就让Q队列的头指针和尾指针都等于0,即指向base[]数组的0的位置,即那块内存空间的首地址
	Q.front=Q.rear=0;
	printf("加油站场景初始化成功!\n");
	return 0;
}

//2.指挥车辆在加油站入口等待
int ComeIn(SqQueue &Q) { //这里传入的队列应为入口队列
	//入队的时候首先需要判断队列是否满了
	if((Q.rear+1)%4==Q.front) {
		printf("当前入口车辆已排满,请指挥车辆进行加油!\n");
		return -1;
	}
	Car input;//定义input变量接收用户输入的入队元素,用Car声明的变量的空间是由系统自动分配的,当然这里也可以使用malloc动态创建内存空间
	printf("请输入进入入口的车辆的车牌号:\n");
	scanf("%s",&input.carName);
	Q.base[Q.rear] = input;//从队尾入队,把输入的数据放到Q队列的base数组的下标为Q.rear的位置
	Q.rear = (Q.rear+1)%4;
	return 0;
}

//3.指挥加油
int Working(SqQueue &Q,SqQueue &C,SqQueue &O) {
	/*
	1.入口车队不空,加油车队不满,出口车队不满:入口车辆出队,出队车辆进入加油车队,车队加油,加油完成进入出口车队
								  出口车队已满:入口车辆出队,出队车辆进入加油车队,车队加油,但不进入出口车队,提示进行车辆出口 *** 作
					加油车队已满,出口车队不满:加油车队出队,进入出口车队,提示加油车队已满,哪辆车进入出口处
								  出口车队已满:提示加油车队已满,出口车队已满,直接提示进行车辆出口 *** 作
	2.入口车队空,加油车队不满,出口车队不满:加油车队出队,进入出口车队
	 							出口车队已满:提示进行出口 *** 作
				  加油车队已满,出口车队不满:加油车队出队,进入出口车队
				  				出口车队已满:提示进行出口 *** 作
	*/
	if(!(C.front==C.rear)) {//入口车队不空
		if(!((Q.rear+1)%4==Q.front)) { //加油车队不满
			if(!((O.rear+1)%4==O.front)) { //出口车队不满
				//入口车辆出队,出队车辆进入加油车队,车队加油,加油完成进入出口车队
				Car output;
				output = C.base[C.front];//从队头出队,记录出队数据
				//打印哪个车辆从入口处进入加油处
				printf("车辆%s从入口处驶入加油处准备加油......\n",output);
				//模拟加油过程 
				printf("加油中......\n");
				printf("5\n");
				printf("4\n");
				printf("3\n");
				printf("2\n");
				printf("1\n");
				printf("车辆%s从加油完毕\n",output);
				//front++,同样这里的++在循环队列中要用(Q.front+1)%MAXQSIZE,来解决假溢出的问题
				C.front = (C.front+1)%4;
				Q.base[Q.rear] = output;//从队尾入队,把输入的数据放到Q队列的base数组的下标为Q.rear的位置
				Q.rear = (Q.rear+1)%4;//rear++,这里的++在循环队列中要用(Q.rear+1)%MAXQSIZE,来解决假溢出的问题
				Car output2;
				output2 = Q.base[Q.front];//从队头出队,记录出队数据
				//front++,同样这里的++在循环队列中要用(Q.front+1)%MAXQSIZE,来解决假溢出的问题
				Q.front = (Q.front+1)%4;
				//打印哪个车辆从加油处进入出口处
				printf("车辆%s驶出加油处,驶入出口处等待......\n",output2);
				O.base[O.rear] = output2;//从队尾入队,把输入的数据放到Q队列的base数组的下标为Q.rear的位置
				O.rear = (O.rear+1)%4;//rear++,这里的++在循环队列中要用(Q.rear+1)%MAXQSIZE,来解决假溢出的问题
			} else { //出口车队已满
				//入口车辆出队,出队车辆进入加油车队,车队加油,但不进入出口车队
				Car output;
				output = C.base[C.front];//从队头出队,记录出队数据
				//打印哪个车辆从入口处进入加油处
				printf("车辆%s从入口处驶入加油处准备加油......\n",output);
				printf("加油中......\n");
				printf("5\n");
				printf("4\n");
				printf("3\n");
				printf("2\n");
				printf("1\n");
				printf("车辆%s从加油完毕,由于出口处车辆已满,该车没有进入出口处\n",output);
				//front++,同样这里的++在循环队列中要用(Q.front+1)%MAXQSIZE,来解决假溢出的问题
				C.front = (C.front+1)%4;
				Q.base[Q.rear] = output;//从队尾入队,把输入的数据放到Q队列的base数组的下标为Q.rear的位置
				Q.rear = (Q.rear+1)%4;//rear++,这里的++在循环队列中要用(Q.rear+1)%MAXQSIZE,来解决假溢出的问题
			}
		} else { //加油车队已满
			if(!((O.rear+1)%4==O.front)) { //出口车队不满
				printf("当前加油处车辆已满,入口车辆无法进入加油处!\n");
				//加油车队出队,进入出口车队
				Car output2;
				output2 = Q.base[Q.front];//从队头出队,记录出队数据
				//front++,同样这里的++在循环队列中要用(Q.front+1)%MAXQSIZE,来解决假溢出的问题
				Q.front = (Q.front+1)%4;
				//打印哪个车辆从加油处进入出口处
				printf("车辆%s驶出加油处,驶入出口处等待......\n",output2);
				O.base[O.rear] = output2;//从队尾入队,把输入的数据放到Q队列的base数组的下标为Q.rear的位置
				O.rear = (O.rear+1)%4;//rear++,这里的++在循环队列中要用(Q.rear+1)%MAXQSIZE,来解决假溢出的问题
				printf("(提示:当前加油处位置有空余,可指挥入口处的车辆进入加油处!\n)");
			} else { 出口车队已满
				//直接提示进行车辆出口 *** 作
				printf("当前加油处的车辆和出口处等待车辆已满!请先指挥车辆驶出加油站\n");
			}
		}
	} else { //入口车队空
		if(!((Q.rear+1)%4==Q.front)) { //加油车队不满
			if(!((O.rear+1)%4==O.front)) { //出口车队不满
				//加油车队出队,进入出口车队
				Car output2;
				output2 = Q.base[Q.front];//从队头出队,记录出队数据
				//front++,同样这里的++在循环队列中要用(Q.front+1)%MAXQSIZE,来解决假溢出的问题
				Q.front = (Q.front+1)%4;
				//打印哪个车辆从加油处进入出口处
				printf("车辆%s驶出加油处,驶入出口处等待......\n",output2);
				O.base[O.rear] = output2;//从队尾入队,把输入的数据放到Q队列的base数组的下标为Q.rear的位置
				O.rear = (O.rear+1)%4;//rear++,这里的++在循环队列中要用(Q.rear+1)%MAXQSIZE,来解决假溢出的问题
				printf("(提示:当前入口处位置为空,可指挥车辆进入入口处!)\n");
			} else { //出口车队已满
				//提示进行出口 *** 作
				printf("当前出口处等待车辆已满!请先指挥车辆驶出加油站\n");
				printf("(提示:当前入口处位置为空,可指挥车辆进入入口处!)\n");
			}
		} else { //加油车队已满
			if(!((O.rear+1)%4==O.front)) { //出口车队不满
				//加油车队出队,进入出口车队
				Car output2;
				output2 = Q.base[Q.front];//从队头出队,记录出队数据
				//front++,同样这里的++在循环队列中要用(Q.front+1)%MAXQSIZE,来解决假溢出的问题
				Q.front = (Q.front+1)%4;
				//打印哪个车辆从加油处进入出口处
				printf("车辆%s驶出加油处,驶入出口处等待......\n",output2);
				O.base[O.rear] = output2;//从队尾入队,把输入的数据放到Q队列的base数组的下标为Q.rear的位置
				O.rear = (O.rear+1)%4;//rear++,这里的++在循环队列中要用(Q.rear+1)%MAXQSIZE,来解决假溢出的问题
				printf("(提示:当前入口处位置为空,可指挥车辆进入入口处!)\n");
			} else { //出口车队已满
				//提示进行出口 *** 作
				printf("当前出口处等待车辆已满!请先指挥车辆驶出加油站\n");
				printf("(提示:当前入口处位置为空,可指挥车辆进入入口处!)\n");
			}
		}
	}
	return 0; 
}

//4.指挥车辆驶出加油站
int ComeOut(SqQueue &Q) { //这里传入的队列应为出口队列
	//出队的时候首先判断队列是否为空		
	if(Q.front==Q.rear) {
		printf("当前出口处无等待车辆!请先指挥车辆进行加油!\n");
		return -1;
	}
	Car output;
	output = Q.base[Q.front];//从队头出队,记录出队数据
	//front++,同样这里的++在循环队列中要用(Q.front+1)%MAXQSIZE,来解决假溢出的问题
	Q.front = (Q.front+1)%4;
	//打印出队元素
	printf("车辆%s已经驶出加油站......\n",output);
	return 0;
}

//5.遍历队列中的元素(增强版) 		可区分遍历哪个队列
int TravelQueue(SqQueue &Q,SqQueue &Work,SqQueue &Out) {
	int whichQueue = 0;//标记变量
	if(&Q.base==&Work.base) {					/*判断传入的第一个变量的地址和哪个队列的地址匹配*/
		whichQueue = 2;
	} else if(&Q.base==&Out.base) {
		whichQueue = 3;
	} else {
		whichQueue = 1;
	}
	int front2 = Q.front;
	switch(whichQueue) {						/*利用switch-case打印不同的提示信息*/
		case 1:
			if(Q.front==Q.rear) {
				printf("当前入口排队车辆为空,请先指挥车辆进入入口排队等待!\n");
				return -1;
			}
			printf("当前入口排队车辆为:");
			while(!(front2==Q.rear)) {
				printf("%s  ",Q.base[front2]);//输出当前base[front2]所表示的元素
				front2=(front2+1)%4;//让front2表示下一次所在的位置
			}
			break;
		case 2:
			if(Q.front==Q.rear) {
				printf("当前加油排队车辆为空,请先指挥入口排队车辆进行加油!\n");
				return -1;
			}
			printf("当前加油排队车辆为:");
			while(!(front2==Q.rear)) {
				printf("%s  ",Q.base[front2]);//输出当前base[front2]所表示的元素
				front2=(front2+1)%4;//让front2表示下一次所在的位置
			}
			break;
		case 3:
			if(Q.front==Q.rear) {
				printf("当前出口排队车辆为空,请先指挥车辆加油!\n");
				return -1;
			}
			printf("当前出口排队车辆为:");
			while(!(front2==Q.rear)) {
				printf("%s  ",Q.base[front2]);//输出当前base[front2]所表示的元素
				front2=(front2+1)%4;//让front2表示下一次所在的位置
			}
			break;
	}
	printf("\n");
	return 0;
}

int main(void) {
	SqQueue Come,Work,Out;//创建三个队列结构体,分别表示入口队列,加油队列,出口队列
	int option;//变量option用于判断用户选择的栈 *** 作
	int loop=1;//变量loop表示循环的条件
	do {
		//菜单
		printf("1.初始化加油站场景\n");
		printf("2.指挥车辆进入加油站\n");
		printf("3.指挥车辆加油\n");
		printf("4.指挥车辆驶出加油站\n");
		printf("5.查看当前入口排队车辆\n");
		printf("6.查看当前加油排队车辆\n");
		printf("7.查看当前出口排队车辆\n");
		printf("8.退出模拟加油站系统\n");
		printf("请输入你的 *** 作:");
		scanf("%d",&option);
		switch(option) {
			case 1://初始化加油站场景
				InitQueue(Come);//调用初始化队列的函数,初始化三个队列,以备 *** 作
				InitQueue(Work);
				InitQueue(Out);
				break;
			case 2://指挥用户进入加油站
				ComeIn(Come);
				break;
			case 3://指挥加油
				Working(Work,Come,Out);
				break;
			case 4://指挥用户驶出加油站
				ComeOut(Out);
				break;
			case 5://查看当前入口排队车辆
				TravelQueue(Come,Work,Out);
				break;
			case 6://查看当前加油排队车辆
				TravelQueue(Work,Work,Out);
				break;
			case 7://查看当前出口排队车辆
				TravelQueue(Out,Work,Out);
				break;
			case 8://退出模拟加油站系统
				loop = 0;
				printf("你退出了模拟加油站系统......");
		}
		printf("\n\n"); //每次执行完换两行,对用户视觉友好
	} while(loop);//循环条件为loop
}
6.注意事项🔊:

上述代码中if的多层嵌套可以简化,读者感兴趣可以自行研究!

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/707039.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-04-24
下一篇 2022-04-24

发表评论

登录后才能评论

评论列表(0条)

保存