(1)假设以数组 sequ[MaxSize]存放环形队列的元素,同时 Rear 和 Len 分别指示 环形队列中队尾元素的位置和内含元素的个数。设计相应的入队 和出队算法。
(2)某汽车轮渡口,过江渡船每次能载 10 辆车过江。过江车辆分别为客车类和货车类,上船有如下规定:同类车先到先上船,客车先于货车上渡船,且每上 4 辆客车,才允许上一辆货车;若等待客车不足 4 辆则以货车代替;若无货车等待则允许客 车都上船。设计一个算法模拟渡口管理。
分析:
(1)解决问题的关键在于以下两点:如何使用软件的方法构造环形队列和如何 通过 Rear 和 Len 来确定队头元素所在的位置。对于第 1 点,通过模运算来实现,即 Rear=(Rear+1)%MaxSize;第 2 个问题,当队尾元素的下标大于队头元素的下标时, 如图 3-1 所示,显然,Rear-Len+1 即为队头元素的下标;当队尾元素的下标小于队头 元素的下标时,如图 3-2 所示,此时队头元素的下标为:(Rear+MaxSize)-Len+1;为 使 这 两 种 情 况 统 一 处 理 , 采 用 以 下 表 达 式 来 计 算 队 头 元 素 的 下 标 : ((Rear+MaxSize)-Len+1)%MaxSize。队空和队满的问题通过 Len 的值即可判断出, Len=0 显然是队空,Len=MaxSize 则为队满。
(2)建立 3 个队列,分别为客车队列 bus,货车队列 truck 和渡船队列 ferry,设 置 3 个变量标识已上渡船的客车数量 busNum、货车数量 truckNum 和总数量 totalNum。当车辆到达渡口时,客车入 bus 队列,货车入 truck 队列。当上渡船的汽车数量 totalNum 小于 10 时,循环扫描客车队列和货车队列,若 busNum<4 且客车队列不为 空,将客车队列的队头汽车出队上船,busNum++,totalNum++;若 busNum<4 且客 车队列为空但货车队列不为空,将货车队列的队头汽车出队上船,置 busNum=0, truckNum++,totalNum++;若 busNum>=4,且货车队列不为空,将货车队列的队头 汽车出队上渡船,置 busNum=0,totalNum++,truckNum++;若客车队列不空但货车 队列为空,则将客车队列的队头汽车出队上渡船,置 totalNum++,busNum++,truckNum =0;若客车队列和货车队列都为空时等待车辆的到达。
我将在第一问的基础上完成第二个问题,具体代码如下。
Cirqueue.h
1 #ifndef SeqList_H
2 #define SeqList_H
3
4 const int MaxSize = 300;
5
6 template <typename DataType> class CirQueue
7 {
8 public:
9 CirQueue() // 构造函数,初始化队列
10 {
11 Len = 0;
12 Rear = MaxSize-1;
13 }
14
15 ~CirQueue() // 析构函数
16 {
17 Len = 0;
18 Rear = MaxSize-1;
19 }
20
21 void EnQueue(DataType x); // 入队操作
22 DataType DeQueue(); // 出队操作
23 int GetLen(); // 返回队列中元素的个数
24 int Statcahr(char a); // 计算当前队列中有多少个char类型字符
25 void DeAll(); // 将队列中所有元素出队
26 private:
27 DataType sequ[MaxSize]; // 存放队列元素的数组
28 int Len, Rear; // 队尾元素的位置和内含元素的个数
29 };
30 # endif
Cirqueue.h
Cirquque.cpp
1 # include <iostream>
2 # include "CirQueue.h"
3 using namespace std;
4
5 // 入队操作
6 template <typename DataType> void CirQueue<DataType>::EnQueue(DataType x)
7 {
8 if (Len == MaxSize)
9 {
10 cout<<"队列已满,入队失败"<<endl;
11 return;
12 }
13 Rear = (Rear + 1) % MaxSize; // 队尾指针在循环意义上+1
14 sequ[Rear] = x;
15 Len++;
16 }
17 // 出队操作
18 template <typename DataType> DataType CirQueue<DataType>::DeQueue()
19 {
20 if (Len == 0) {
21
22 return ' ';
23 }
24 int i = ((Rear+MaxSize)-Len+1) % MaxSize; // 获取队列第一个元素的下标
25 Len--;
26 return sequ[i];
27 }
28 // 输出当前队列有多少元素
29 template <typename DataType> int CirQueue<DataType>::GetLen()
30 {
31 return Len;
32 }
33
34 // 计算当前队列中有多少个char类型字符
35 template <typename DataType> int CirQueue<DataType>::Statcahr(char a)
36 {
37 int count=0, j = ((Rear+MaxSize)-Len+1) % MaxSize; // 统计char a的个数 , 获取第一个元素下标
38 for (int i=0; i < Len; i++)
39 {
40 if (sequ[j] == a)
41 {
42 j++;
43 }
44 }
45
46 return count;
47 }
48
49 // 将队列中所有元素出队
50
51 template <typename DataType> void CirQueue<DataType>::DeAll()
52 {
53 int j = Len;
54 for (int i = 0; i < j; i++)
55 {
56 cout<<DeQueue();
57 }
58 }
Cirquque.cpp
CirQueue_main.cpp
1 # include "CirQueue.cpp"
2 # include <cstdlib>
3
4 CirQueue<char> awaitcar; // awaitcar等待上船的客车队列
5 CirQueue<char> awaittruck; // awaittruck等待上船的货车队列
6
7 // 函数功能:渡船
8 void ship()
9 {
10 CirQueue<char> ship10; // 定义船
11 // 设置 3 个变量标识已上渡船的客车数量 busNum、货车数量 truckNum 和总数量 totalNum
12 int busNum, truckNum, totalNum, j=0; // j代表第几辆船
13
14 while (awaitcar.GetLen()!=0 || awaittruck.GetLen()!=0) // 如果岸上还有车那么就循环
15 {
16 busNum=0, truckNum=0, totalNum=0;
17 while (totalNum < 10) // 如果船没有满,那么就可以上船
18 {
19 if (busNum < 4 && awaitcar.GetLen() != 0) // 船上的客车没满4辆并且岸上还有客车
20 {
21 ship10.EnQueue(awaitcar.DeQueue()); // 那么就上一辆客车
22 busNum++;
23 totalNum++;
24 }
25 else if (busNum < 4 && awaitcar.GetLen() == 0) // 船上的客车没满4辆并且岸上没有客车
26 {
27 ship10.EnQueue(awaittruck.DeQueue()); // 那么就上一辆货车
28 truckNum++;
29 totalNum++;
30 busNum=0;
31 }
32 else if (busNum >= 4 && awaittruck.GetLen() != 0)// 如果穿上已经上了四辆客车并且岸上还有货车
33 {
34 ship10.EnQueue(awaittruck.DeQueue()); // 那么就上一辆货车
35 truckNum++;
36 totalNum++;
37 busNum=0;
38 }
39 else if (busNum >= 4 && awaittruck.GetLen() == 0)// 如果穿上已经上了四辆客车并且岸上没有货车
40 {
41 ship10.EnQueue(awaitcar.DeQueue()); // 那么就上一辆客车
42 busNum++;
43 totalNum++;
44 }
45 }
46 j++;
47 cout<<"这是第"<<j<<"辆船,船上的装载情况为:";
48 ship10.DeAll();
49 ship10.~CirQueue();
50 totalNum=0;
51 cout<<endl;
52 }
53 }
54
55 int main(void)
56 {
57 int alltruck, allcar; // alltruck等待上船的货车数量, allcar等待上船的客车数量
58
59 while (true) // 为了测试数据方便,这里设置为永真
60 {
61 cout<<"请输入当前正在等待上船的客车数量:";
62 cin>>allcar;
63 cout<<"请输入当前正在等待上船的货车数量:";
64 cin>>alltruck;
65
66
67 for (int i=0; i< allcar; i++) // * 代表客车
68 {
69 awaitcar.EnQueue('*');
70 }
71 for (int i=0; i< alltruck; i++) // # 代表货车
72 {
73 awaittruck.EnQueue('#');
74 }
75
76 ship();
77 cout<<endl;
78 awaitcar.~CirQueue();
79 awaittruck.~CirQueue();
80 }
81
82 system("pause");
83 return 0;
84 }
CirQueue_main.cpp