数据结构栈与队列的应用之汽车轮渡问题——自己的一些理解

本题摘自王道数据结构栈与队列的应用的课后题,题目如下:

某汽车轮渡口,过江渡船每次能载10辆汽车过江。过江车辆分为客车类和货车类,上渡船有如下规定:同类车先到先上船,客车先于货车上船,且每上4辆客车,才允许放上一辆货车;若等待客车不足4辆,则以货车替代;若无货车等待,允许客车都上船。试设计一个算法模拟渡口管理。

乍一看题目好像很复杂,但是,仔细读一下,发现无非就是几种情况而已。从这个同类车先到先上船,我们就可以考虑到这道题需要利用队列FIFO的性质。

王道书中所给的算法设计思想是:假设数组q的最大下标为10,恰好是每次载渡的最大量。假设客车的队列是q1,货车的队列为q2。若q1充足,则每取4个q1元素后再取一个q2元素,直到q的长度为10。若q1不充足,则直接用q2补齐。算法的实现如下:

void Manager(SqQueue *q,SqQueue *q1,SqQueue *q2){
	char x;
	int i=0,j=0;//i表示渡船上的客车数量,j表示渡船上的总车辆数
	while(j<10){
		if(!IsEmpty(q1)&&i<4){
			DeQueue(&q1,&x);
			EnQueue(&q,x);
			i++;
			j++
		}
		else if(i==4&&!IsEmpty(q2)){
			DeQueue(&q2,&x);
			EnQueue(&q,x);
			j++;
			i=0;//每上一辆货车,i都要重新计数
		}
		else{                        //其他情况(客车队列空或者货车队列空)
			while(j<10&&i<4&&!IsEmpty(q2)){
				DeQueue(&q2,&x);
				EnQueue(&q,x);
				i++;//用货车代替客车
				j++;
			}
			i=0;//这个i=0是这个代码的点睛之笔          
		}
		if(IsEmpty(q1)&&IsEmpty(q2))
			j=11;//若货车跟客车加起来都没有10辆则直接赋值j=11跳出这个最外层循环
	}
	
}
int main(){
	SqQueue q;//过江渡船载渡队列
	SqQueue q1;//客车队列
	SqQueue q2;//货车队列
	Manager(&q,&q1,&q2);
	return 0;
}

代码的核心部分就是上述代码,在我看来,上述代码中第一个if以及else if里面的代码都是比较好理解的,根据题意写出来即可。题目后面所提到的i=0是点睛之笔是我认为比较难理解的地方。我第一遍做这道题的时候,感觉题目中后面两个条件不好实现,即“若等待客车不足4辆,则以货车替代;若无货车等待,允许客车都上船。”第一遍写的时候总是感觉用上述代码实现会漏掉某种情况,后来又仔细读了几遍代码,读到这个i=0才恍然大悟。

这个点睛之笔i=0,如果客车队列为空,则会一直执行上面的代码(即else里面的while),让货车替代客车;若货车队列空,则当第一个if执行完毕后,将i赋值为0,继续执行第一个if,即无货车等待,允许客车全部上船。这样就完美解决了所有可能出现的情况。

以上内容均是自己的一些理解,欢迎大家的指导和交流。

你可能感兴趣的:(数据结构,c语言)