队列模板简单应用算法设计:士兵队列训练
时间限制: 1S类别: DS:队列->队列定义及应用
晚于: 2022-05-04 23:55:00后提交分数乘系数50%
截止日期: 2022-05-08 23:55:00
问题描述 :
目的:使用C++模板设计队列(链队列和顺序队列)的抽象数据类型(ADT)。并在此基础上,使用队列ADT的基本操作,设计并实现简单应用的算法设计。
内容:(1)请参照栈的ADT模板,设计队列的抽象数据类型。(由于该环境目前仅支持单文件的编译,故将所有内容都集中在一个源文件内。在实际的设计中,推荐将抽象类及对应的派生类分别放在单独的头文件中。参考教材、课件,以及网盘中的栈ADT原型文件,自行设计队列的ADT。)
(2)ADT的简单应用:使用该ADT设计并实现若干应用队列的算法设计。
应用:某部队进行新兵队列训练,将新兵从一开始按顺序依次编号,并排成一行横队,训练的规则如下:从头开始一至二报数,凡报到二的出列,剩下的向小序号方向靠拢,再从头开始进行一至三报数,凡报到三的出列,剩下的向小序号方向靠拢,继续从头开始进行一至二报数。。。,以后从头开始轮流进行一至二报数、一至三报数直到剩下的人数不超过三人为止。
要求设计一个算法,使用链队列或顺序队列(只能使用1个队列),设计并实现打印输出剩下的新兵最初的编号的算法。
注意:本题允许有多个测试数据组,新兵总人数不超过5000。由于士兵可能的总人数较多,顺序队列需预先申请的存储空间较大,建议使用链队列。(样例程序使用的是链队列。)
参考函数原型:
template
void queuetraining(SqQueue &S, int T); //T为测试数据的组数
/* 链队列的结点定义 */
template
struct LinkQueueNode
{
ElemType data;
LinkQueueNode *next;
LinkQueueNode(LinkQueueNode *ptr = NULL){next = ptr;} //构造函数1,用于构造头结点
LinkQueueNode(const ElemType &item, LinkQueueNode *ptr = NULL) //构造函数2,用于构造其他结点
//函数参数表中的形参允许有默认值,但是带默认值的参数需要放后面
{
next = ptr;
data = item;
}
ElemType getData(){ return data;} //取得结点中的数据
void SetLink( LinkQueueNode *link ){ next = link; } //修改结点的next域
void SetData( ElemType value ){ data = value; } //修改结点的data域
};
//带头结点的链队列
template
class LinkQueue{
private:
LinkQueueNode *front; // 队头指针
LinkQueueNode *rear; // 队尾指针
int length; //队列当前元素个数
public:
//无参数的构造函数
LinkQueue();
//析构函数
~LinkQueue(){LinkQueueDestroy();}
//销毁链队列
bool LinkQueueDestroy();
//清空链表
bool LinkQueueClear();
//返回链队列的长度
int QueueLength() const{ return length;}
//判断链队列是否为空队列
bool QueueisEmpty() const;
//出队
bool deQueue( ElemType &e );
//入队
bool enQueue( ElemType e );
//获取链队列头结点指针
LinkQueueNode* GetFront() { return front;}
//获取队头元素
ElemType GetFrontData(){ if(front->next) return front->next->data;}
//获取链队列队尾指针
LinkQueueNode* GetRear() { return rear;}
//遍历链队列
bool QueueTraverse() const;
};
输入说明 :
第一行:组数N,
第二行-第N+1行:每组的新兵人数
输出说明 :
第一行:
.
. 剩下的新兵最初的编号,编号之间有用","分隔。
.
第N行:
输入范例 :
2
20
40
输出范例 :
1,7,19
1,19,37
这题目要求不清不楚的 改了好几次才知道它是咋排的
#include
#include
#include
using namespace std;
#define Status int
typedef int QElemType;
//队列的顺序存储结构
#define MAXQSIZE 100 //队列可能达到的最大长度
typedef struct QNode //结点定义
{
QElemType data;
struct QNode* next;
}QNode, * QueuePtr;
typedef struct //队列定义
{
QueuePtr front; //队头指针
QueuePtr rear; //队尾指针
}LinkQueue;
Status InitQueue(LinkQueue& Q)
{//构造一个空队列Q
Q.front = Q.rear = new QNode; //生成新结点作为头结点,队头和队尾指针指向此节点
Q.front->next = NULL; //头结点的指针域置空
return 1;
}
Status EnQueue(LinkQueue& Q, QElemType e)
{//插入元素e作为Q的新队尾元素
QNode* p = new QNode; //分配空间
p->data = e; //赋值
p->next = NULL;
Q.rear->next = p; //插入队列
Q.rear = p; //修改队尾指针
return 1;
}
Status DeQueue(LinkQueue& Q, QElemType &e)
{//删除Q队头元素并用e返回其值
if (Q.front == Q.rear)
return 0; //判断队空
QNode* p = Q.front->next; //p指向队头元素
e = p->data; //用e保存队头元素值
Q.front->next = p->next; //出队
if (Q.rear == p) //如果出队后空队,队尾指针指向头结点
Q.rear = Q.front;
delete p; //释放空间
return 1;
}
QElemType GetHead(LinkQueue Q)
{//返回Q的队头元素,不修改头指针
if (Q.rear != Q.front) //判断队空
return Q.front->next->data; //返回队头元素值
}
typedef struct
{
QElemType* base; //存储空间的基地址
int front; //头指针
int rear; //尾指针
}SqQueue;
Status InitQueue(SqQueue& Q)
{//构建一个空队列Q
Q.base = new QElemType[MAXQSIZE]; //为队列分配一个最大容量为MAXQSIZE的数组空间
Q.front = Q.rear = 0; //头指针和尾指针置为0,队列为空
return 1;
}
int QueueLength(SqQueue Q)
{
return (Q.rear - Q.front + MAXQSIZE) % MAXQSIZE;
}
Status EnQueue(SqQueue& Q, QElemType e)
{//插入元素e为Q的新的队尾元素
if ((Q.rear + 1) % MAXQSIZE == Q.front) //判断是否队满
return 0;
Q.base[Q.rear] = e; //插入元素
Q.rear = (Q.rear + 1) % MAXQSIZE; //队尾指针加1
return 1;
}
Status DeQueue(SqQueue& Q, QElemType& e)
{//删除Q的队头元素,用e返回其值
if (Q.rear == Q.front) //判断队空
return 0;
e = Q.base[Q.front];
Q.front = (Q.front + 1) % MAXQSIZE; //队头指针加1
return 1;
}
QElemType GetHead(SqQueue Q)
{//返回Q的队头元素,不修改头指针
if (Q.rear != Q.front) //判断队空
return Q.base[Q.front]; //返回队头元素值
}
QElemType GetTail(SqQueue Q)
{//返回Q的队尾元素,不修改头指针
if (Q.rear != Q.front) //判断队空
return Q.base[Q.rear - 1]; //返回队尾元素值
}
void queuetraining(LinkQueue& S, int T) //T 为测试数据的组数
{
int x = 0, ok = 1, y = 0,p=T;
while (S.front->next->next->next != 0)
{
if (S.front->next->data == 1)
{
if (ok == 0)
{
ok = 1;
if (S.front->next->next->next->next == 0)
break;
}
else
{
ok = 0;
if (S.front->next->next->next->next == 0)
break;
}
x = 0;
}
x++;
if (x == 2 && ok == 0)
{
x = 0;
DeQueue(S, y);
continue;
}
else if (x == 3 && ok == 1)
{
x = 0;
DeQueue(S, y);
continue;
}
else
{
DeQueue(S, y);
EnQueue(S, y);
}
}
while (S.front->next->data!=1)
{
DeQueue(S, y);
EnQueue(S, y);
}
if (S.front->next->next->next == 0)
cout << S.front->next->data << "," << S.front->next->next->data;
else if (S.front->next->next == 0)
cout << S.front->next->data;
else if (S.front->next->next->next->next == 0)
cout << S.front->next->data << "," << S.front->next->next->data << "," << S.front->next->next->next->data;
else
return;
return;
}
int main()
{
int n, m;
cin >> n ;
int N = n, i = 1;
while (N--)
{
cin >> n;
m = n;
LinkQueue S;
InitQueue(S);
i = 1;
while (n--)
{
EnQueue(S, i);
i++;
}
queuetraining(S, m);
cout << endl;
}
return 0;
}