队列是一种抽象的数据类型(ADT),可以存储有序的项目序列.新项目被添加到队尾,并可以删除队首项目。队列有点像堆栈,不过堆栈在同一端进行添加和删除。这使得栈是一种先进后出(LIFO)的结构,而队列是先进先出的(FIFO)。从概念说说,队列就好比是收款台或者ATM前面排的队,所以对于上诉结构问题,队列非常合适。因此,工程的任务之一是定义个Queue类。
队列中的项目就是顾客,Heather银行的代表介绍:通常,三分之一的顾客只需要一分钟便可获得服务,三分之一的顾客需要两分钟,另外三分之的顾客需要三分钟。
另外,顾客到达的时间是随机的,但每个小时使用自动柜员机的顾客数量相当稳定。工程的另外两个任务是:设计一个表示顾客的类;编写一个程序来模拟顾客和队列之间的交互。
1.队列类
首先需要设计一个Queue类。这里先列出队列的特征:
1)队列存储有序的项目序列2)队列所能容纳的项目数有一定限制
3)应当能够创建空队列
4)应当能够检查队列是否为空
5)应当能够检查队列是否满的
6)应当能够在队尾添加项目
7)应当能够在队首删除项目
8)应当鞥能够确定队列中项目数
2.类设计
1.queue.h头文件
#ifndef _QUEUE_H_ #define _QUEUE_H_ 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: struct Node { Item item; struct Node *next; }; enum { Q_SIZE = 10 }; Node *front; Node *rear; const int qsize; Queue(const Queue & q):qsize(0){} Queue & operator=(const Queue & q){return *this; } public: Queue(int qs = Q_SIZE); ~Queue(); bool isempty() const; bool isfull() const; int queuecount() const; bool enqueue(const Item &item); bool dequeue(Item &item); }; #endif
2.queue.cpp
#include "StdAfx.h" #include "queue.h" #include <cstdlib> Queue::Queue(int qs):qsize(qs) { front = rear = NULL; items = 0; } Queue::~Queue() { Node *temp; while(front != NULL) { temp = front; front = front->next; delete temp; } } bool Queue::isempty() const { return items == 0; } bool Queue::isfull() const { return items == qsize; } int Queue::queuecount() const { return items; } bool Queue::enqueue(const Item &item) { if (isfull()) return false; Node *add = new Node(); if (add == NULL) return false; //内存不足,无法分配空间 add->item = item; //添加数据 add->next = NULL; //下一个置为空 items++; if(front == NULL) front = add; else rear->next = add; //将最后一个节点指向新分配节点 rear = add; //添加到队尾 return true; } bool Queue::dequeue(Item &item) { if (front == NULL) return false; item = front->item; //将首节点数据复制到引用变量中 items--; Node *temp = front; //保存首节点地址 front =front->next; //重置首节点指针 delete temp; if (items == 0) rear = NULL; return true; } void Customer::set(long when) { processtime = std::rand() % 3 +1; arrive = when; }
3.测试
// ch12_queue.cpp : 定义控制台应用程序的入口点。 // #include "stdafx.h" #include "queue.h" #include <iostream> #include <ctime> const int MIN_PER_HR = 60; bool newcustomer(double x); using namespace std; int _tmain(int argc, _TCHAR* argv[]) { std::srand(std::time(0)); cout<<"Case Study: Bank of Heather Automatic Teller\n;"; cout<<"Enter maximum size of queue: "; int qs; cin>>qs; Queue line(qs); cout<<"Enter the number of simulation hours: "; int hours; cin>>hours; long cyclelimit = MIN_PER_HR * hours; cout<<"Enter the average number of customers per hour: "; double perhour; cin>>perhour; double min_per_cust; min_per_cust = MIN_PER_HR; Item temp; long turnaways = 0; long customers = 0; long served = 0; long sum_line = 0; int wait_time = 0; long line_wait = 0; for (int cycle = 0; cycle < cyclelimit; cycle++) { if (newcustomer(min_per_cust)) { if (line.isfull()) turnaways++; else { customers++; temp.set(cycle); //设置到达时间 line.enqueue(temp);//加入队列 } } if(wait_time <= 0 && !line.isempty()) { line.dequeue(temp); wait_time = temp.ptime(); line_wait += cycle - temp.when(); served++; } if (wait_time > 0) wait_time--; sum_line += line.queuecount(); } if (customers > 0) { cout<<"curtomers accepted: "<< customers<<endl; cout<<" curtomers served: " <<served <<endl; cout<<" turnaways: "<<turnaways<<endl; cout<<"average queue size: "; cout.precision(2); cout.setf(ios_base::fixed,ios_base::floatfield); cout.setf(ios_base::showpoint); cout<<(double)sum_line / cyclelimit <<endl; cout<<" average wait time: "<<(double) line_wait / served <<" minutes\n"; } else cout<<"No customers\n"; cout<<"Done\n"; return 0; } bool newcustomer(double x) { return (rand() * x / RAND_MAX < 1); }