<队列>队列模拟

队列模拟
  队列是一种抽象的数据类型,可以储存有序的数据序列,新数据被添加到队列尾,
  并可以删除队列首的数据,队列有点像栈,但栈在同一端进行进行添加和删除
  数组中第一个元素出队列了,后面的元素都要往前移动,工作量非常大。使用链表的思想来解决

链表
  链表在内存中不是连续分布的,数组在内存中是连续分布的。把不同的内存空间通过链条连接
  所以每个节点需要保存两个内容:一个是链表成员,一个是指向下一个节点的指针,即单向链表
  链表节点:
  struct Node
  {
      Item item;
      // 结构体嵌套
      struct Node* next;
  }

成员初始化列表:
  这种格式只能用于构造函数
  必须使用这种格式来初始化非静态const类成员 
    const int a;
  必须用这种格式来初始化被声明为引用的类成员
    private:
        Agency& belong;// 必须要使用初始化列表来初始化
    Agent::Agent(Agency & a) : belong(a)

↓_p_front
[item1|p_next] null
↑_p_rear     ↓_↑

↓_p_front      ↓_p_rear
[item1|p_next] [item2|p_next] null
             ↓_↑            ↓_↑

↓_p_front                     ↓_p_rear
[item1|p_next] [item2|p_next] [item3|p_next] null
             ↓_↑            ↓_↑            ↓_↑

----------------------------------------------

               ↓_p_front      ↓_p_rear
               [item2|p_next] [item3|p_next] null
                           ↓_↑            ↓_↑

                              ↓_p_front = ↓_p_rear
                              [item3|p_next] null
                                           ↓_↑

                                             ↓_p_front = ↓_p_rear
                                             null
#include <iostream>
#include "ATM.h"
using namespace std;

// 入队列,队列满了之后再出队列
int main()
{   
    int qs;
    int time = 0;
    int num_customers = 0;
    // 类对象客户
    Item temp;

    cout << "输入队列的最大尺寸:";
    cin >> qs;

    Queue line(qs);

    // 入队列直到队列满
    while(!line.isfull())
    {
        temp.set(time++);
        // 顾客入队列
        line.enqueue(temp);
        num_customers++;
    }

    cout << "入队列后顾客的数量 = " << num_customers << endl;


    // -----------------------------------
    
    while(!line.isempty())
    {
        line.dequeue();
        num_customers--;
    }

    cout << "出队列后现在顾客的数量 = " << num_customers << endl;

    return 0;
}

ATM.cpp


#include "ATM.h"
#include <stdlib.h>

// notice: 函数体{}中的代码执行前,对象就会被创建,编译器就会为成员变量分布内存空间(就相当于初始化)
// 对于const成员,必须在执行到函数体之前,进行对象成员的初始化
Queue::Queue(int qs):qsize(qs)
{

    p_front = p_rear = NULL;
    // 当前排队人数
    num_items = 0;
    // 最大排队人数,如果不适用成员初始化列表,创建对象时已经初始化了,现在相当于改变qsize的值了
    // qsize = qs;
}

Queue::~Queue()
{
    cout << "调用析构函数!" << endl;
    Node* temp;
    while(p_front != NULL)
    {
        temp = p_front;
        p_front = p_front->p_next;
        delete temp;
    }

}

bool Queue::isempty() const
{
    return num_items == 0;
}

bool Queue::isfull() const
{
    return num_items == qsize;
}

int Queue::queuecount() const
{
    return num_items;
}

// 引用传递,从队列尾部入队列
bool Queue::enqueue(const Item& item)
{
    if(isfull())
        return false;
    
    // 创建存放新队列的节点
    Node* add_new = new Node;
    // 拷贝构造函数,初始化数据域
    add_new->item = item;
    // 每一次添加新节点的p_next都是空
    add_new->p_next = NULL;

    num_items++;

    // 如果是第一次添加节点,链表头指针为空
    if(p_front == NULL)
        p_front = add_new;
    else// 如果不是第一次
        // 上一个节点(之前队列的最后一个节点)的p_next指向当前的新节点
        p_rear->p_next = add_new;

    // 更新,新加入的节点作为尾节点
    p_rear = add_new;

    return true;
}

// 引用传递,从队列头部出队列
bool Queue::dequeue()
{
    if(p_front == NULL)
        return false;


    num_items--;

    // 先临时保留第一个节点
    Node* temp = p_front;

    // notice: 头指针下移:删除头节点之前,先让二号节点成为(代替)头节点
    p_front = p_front->p_next;
    // 头指针下移之后才能删除原来第一个节点指向的内存
    delete temp;

    if(num_items == 0)
        p_rear = NULL;

    return true;

}

// 输入开始取款的时间
void Customer::set(long when)
{
    arrive = when;
    // 1~3分钟
    processtime = rand() % 3 + 1;
}

ATM.h

#ifndef __ATM_H__
#define __ATM_H__


#include <iostream>
using namespace std;

class Customer
{
    private:
        // 开始取钱的时间
        long arrive;
        // 取钱过程花费的时间
        int processtime;
    public:
        Customer(){arrive = processtime = 0;}

        void set(long when);
        long when() const {return arrive;};
        int ptime() const {return processtime;}

};


typedef Customer Item;


class Queue
{
    private:
        // 队列默认长度,类中定义常量:枚举、静态常量
        enum{Q_SIZE = 10};
        // 链表节点
        struct Node
        {
            // 类对象
            Item item;
            struct Node* p_next;
        };
        
        // 链表头
        Node* p_front;
        // 链表尾
        Node* p_rear;

        // 当前排队的人数,节点个数
        int num_items;
        // 队列最大值,最大排队人数不能改变
        // 函数体{}中的代码执行前,对象就会被创建,编译器就会为成员变量分布内存空间(就相当于初始化)
        // notice: 对于const成员,必须在执行到函数体之前,进行对象成员的初始化
        const int qsize;

    public:
        // 成员初始化列表
        Queue(int qs = Q_SIZE);
        ~Queue();
        bool isempty() const;
        bool isfull() const;
        // 节点个数,当前排队人数
        int queuecount() const;

        // 引用传递
        bool enqueue(const Item& item);

        bool dequeue();

};






#endif 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值