队列模板简单应用算法设计:士兵队列训练
时间限制: 1s
类别: DS:队列->队列定义及应用
问题描述
目的:使用C++模板设计队列(链队列和顺序队列)的抽象数据类型(ADT)。并在此基础上,使用队列ADT的基本操作,设计并实现简单应用的算法设计。
内容:(1)请参照栈的ADT模板,设计队列的抽象数据类型。(由于该环境目前仅支持单文件的编译,故将所有内容都集中在一个源文件内。在实际的设计中,推荐将抽象类及对应的派生类分别放在单独的头文件中。参考教材、课件,以及网盘中的栈ADT原型文件,自行设计队列的ADT。)
(2)ADT的简单应用:使用该ADT设计并实现若干应用队列的算法设计。
应用:某部队进行新兵队列训练,将新兵从一开始按顺序依次编号,并排成一行横队,训练的规则如下:从头开始一至二报数,凡报到二的出列,剩下的向小序号方向靠拢,再从头开始进行一至三报数,凡报到三的出列,剩下的向小序号方向靠拢,继续从头开始进行一至二报数。。。,以后从头开始轮流进行一至二报数、一至三报数直到剩下的人数不超过三人为止。
要求设计一个算法,使用链队列或顺序队列(只能使用1个队列),设计并实现打印输出剩下的新兵最初的编号的算法。
注意:本题允许有多个测试数据组,新兵总人数不超过5000。由于士兵可能的总人数较多,顺序队列需预先申请的存储空间较大,建议使用链队列。(样例程序使用的是链队列。)
参考函数原型:
template<class ElemType>
void queuetraining(SqQueue<ElemType> &S, int T); //T为测试数据的组数
#include<iostream>
#include<string>
using namespace std;
template<class ElemType>
struct LinkQueueNode
{
ElemType data;
LinkQueueNode<ElemType> *next;
LinkQueueNode(LinkQueueNode<ElemType> *ptr = NULL)
{
next = ptr;
}
LinkQueueNode(const ElemType &item, LinkQueueNode<ElemType> *ptr = NULL)
{
next = ptr;
data = item;
}
ElemType getData()
{
return data;
}
void SetLink( LinkQueueNode<ElemType> *link )
{
next = link;
}
void SetData( ElemType value )
{
data = value;
}
};
template<class ElemType>
class LinkQueue
{
private:
LinkQueueNode<ElemType> *front;
LinkQueueNode<ElemType> *rear;
int length;
public:
LinkQueue();
~LinkQueue()
{
LinkQueueDestroy();
}
bool LinkQueueDestroy();
bool LinkQueueClear();
int QueueLength() const
{
return length;
}
bool QueueisEmpty() const;
bool deQueue( ElemType &e );
bool deQueue();
bool enQueue( ElemType e );
LinkQueueNode<ElemType>* GetFront()
{
return front;
}
bool pop() ;
ElemType GetFrontData()
{
if(front->next) return front->next->data;
}
LinkQueueNode<ElemType>* GetRear()
{
return rear;
}
bool QueueTraverse() const;
void queuetraining(LinkQueue<ElemType> &q);
};
template<class ElemType>
LinkQueue<ElemType>::LinkQueue()
{
front=new LinkQueueNode<ElemType>();
rear=front;
length=0;
}
template<class ElemType>
bool LinkQueue<ElemType>::LinkQueueDestroy()
{
while (front)
{
LinkQueueNode<ElemType> *temp = front;
front = front->next;
delete temp;
}
rear = nullptr;
length = 0;
return true;
}
template<class ElemType>
bool LinkQueue<ElemType>::LinkQueueClear()
{
LinkQueueNode<ElemType> *current=front->next;
while(current)
{
LinkQueueNode<ElemType> *temp=current;
current=current->next;
delete temp;
}
front->next=nullptr;
rear=front;
length=0;
return 1;
}
template<class ElemType>
bool LinkQueue<ElemType>::QueueisEmpty() const
{
return front==rear;
}
template<class ElemType>
bool LinkQueue<ElemType>::deQueue(ElemType &e)
{
if (QueueisEmpty())
{
return false;
}
LinkQueueNode<ElemType> *temp = front->next;
e = temp->data;
front->next = temp->next;
if (rear == temp)
{
rear = front;
}
delete temp;
length--;
return true;
}
template<class ElemType>
bool LinkQueue<ElemType>::deQueue()
{
if (QueueisEmpty())
{
return false;
}
LinkQueueNode<ElemType> *temp = front->next;
front->next = temp->next;
if (rear == temp)
{
rear = front;
}
delete temp;
length--;
return true;
}
template<class ElemType>
bool LinkQueue<ElemType>::enQueue(ElemType e)
{
LinkQueueNode<ElemType> *newNode = new LinkQueueNode<ElemType>(e);
rear->next = newNode;
rear = newNode;
length++;
return true;
}
template<class ElemType>
bool LinkQueue<ElemType>::QueueTraverse() const
{
LinkQueueNode<ElemType> *current = front->next;
while (current != nullptr)
{
cout << current->data << " ";
current = current->next;
}
cout << endl;
return true;
}
template<class ElemType>
void LinkQueue<ElemType>::queuetraining(LinkQueue<ElemType> &q)
{
int p = 1, x, k;
while(q.QueueLength() > 3)
{
x = q.QueueLength();
if(p % 2 == 1)
{
for(int i = 0; i < x / 2; ++i)
{
q.deQueue(k);
q.enQueue(k);
q.deQueue();
}
if(x % 2 == 1)
{
q.deQueue(k);
q.enQueue(k);
}
}
else
{
for(int i = 0; i < x / 3; ++i)
{
q.deQueue(k);
q.enQueue(k);
q.deQueue(k);
q.enQueue(k);
q.deQueue();
}
while(x % 3 != 0)
{
q.deQueue(k);
q.enQueue(k);
x--;
}
}
p++;
}
ElemType e;
while(q.QueueLength() > 1)
{
q.deQueue(e);
cout << e <<',';
}
q.deQueue(e);
cout << e << endl;
}
int main()
{
int N;
cin >> N;
while(N--)
{
int num;
cin >> num;
LinkQueue<int> q;
for(int i = 1; i <= num; ++i)
q.enQueue(i);
q.queuetraining(q);
}
return 0;
}