dhu 4.1 队列模板简单应用算法设计:士兵队列训练

28 篇文章 5 订阅

队列模板简单应用算法设计:士兵队列训练
时间限制: 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<ElemType> *next;

LinkQueueNode(LinkQueueNode<ElemType> *ptr = NULL){next = ptr;} //构造函数1,用于构造头结点

LinkQueueNode(const ElemType &item, LinkQueueNode<ElemType> *ptr = NULL) //构造函数2,用于构造其他结点   

//函数参数表中的形参允许有默认值,但是带默认值的参数需要放后面

{

    next = ptr;

    data = item;

}

ElemType getData(){ return data;}  //取得结点中的数据

void SetLink( LinkQueueNode<ElemType> *link ){ next = link; }  //修改结点的next域 

void SetData( ElemType value ){ data = value; }   //修改结点的data域

};

//带头结点的链队列

template

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 enQueue( ElemType e );

  //获取链队列头结点指针 

  LinkQueueNode<ElemType>* GetFront() { return front;}

  //获取队头元素

  ElemType GetFrontData(){ if(front->next) return front->next->data;}      

  //获取链队列队尾指针

  LinkQueueNode<ElemType>* GetRear() { return rear;}

  //遍历链队列 

  bool QueueTraverse() const;

};

输入说明 :

第一行:组数N,

第二行-第N+1行:每组的新兵人数

输出说明 :

第一行:

.

. 剩下的新兵最初的编号,编号之间有用","分隔。

.

第N行:

输入范例 :

2
20
40
输出范例 :

1,7,19
1,19,37

这题目要求不清不楚的 改了好几次才知道它是咋排的

#include <iostream>
#include <cstring>
#include <string>
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;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值