C++Primer Plus 第12章 类和动态内存分配::队列模拟----链表,堆栈,链表的方法的理解001

12.7 队列模拟

进一步了解类后,可将这方面的知识用于解决编程问题。Heather 银行打算在 Food Heap 超市开设一个自动柜员机(ATM)。FoodHeap超市的管理者担心排队等待使用ATM的人流会干扰超市的交通,希望限制排队等待的人数。Heather 银行希望对顾客排队等待的时间进行估测。要编写一个程序来模拟这种情况,让超市的管理者可以了解 ATM 可能造成的影响。
对于这种问题,最自然的方法是使用顾客队列。队列是一种抽象的数据类型(AbstractDataType,ADT)可以存储有序的项目序列。新项目被添加在队尾,并可以删除队首的项目。队列有点像栈,但栈在同一端进行添加和删除。这使得栈是一种后进先出(LIFO,last-in,first-out)的结构,而队列是先进先出(FIFO,first-in,frst-out)的。从概念上说,队列就好比是收款台或 ATM 前面排的队,所以对于上述问题,队列非常合适。因此,工程的任务之一是定义一个Queue类(第16章将介绍标准模板库类 queue,也将介绍如何开发自己的类)。
队列中的项目是顾客。Heather银行的代表介绍:通常,三分之一的顾客只需要一分钟便可获得服务。三分之一的顾客需要两分钟,另外三分之一的顾客需要三分钟。另外,顾客到达的时间是随机的,但每个小时使用自动柜员机的顾客数量相当稳定。工程的另外两项任务是:设计一个表示顾客的类;编写一个程序来模拟顾客和队列之间的交互(参见图12.7)。
在这里插入图片描述
12.7.1 队列类
首先需要设计一个Queue 类。这里先列出队列的特征:队列存储有序的项目序列:
1,队列所能容纳的项目数有一定的限制;
2,应当能够创建空队列;
3,应当能够检查队列是否为空;
4,应当能够检查队列是否是满的;
5,应当能够在队尾添加项目;
6,应当能够从队首删除项目;
7, 应当能够确定队列中项目数。
设计类时,需要开发公有接口和私有实现。

1.Queue 类的接口
从队列的特征可知,Queue 类的公有接口应该如下:

class Queue
{
	enum { Q_SIZE = 10 };

private:
	//privat representation to be developed later

public:
	Queue(int qs = Q_SIZE);
	~Queue();
	bool isempty()const;
	bool isfull()const;
	int queuecount()const;
	bool enqueue(const Item& item);//add item to end
	bool dequeue(Item& item);//remove item from front
};

构造函数创建一个空队列。默认情况下,队列最多可存储 10个项目,但是可以用显式初始化参数覆盖该默V

Queue linel;// queue with 10-item limit
Queue line2(20);// queue with 20-item limit

使用队列时,可以使用typedef来定义Item(第14章将介绍如何使用类板)。

2 Queue 类的实现
确定接口后,便可以实现它。首先,需要确定如何表示队列数据。一种方法是使用 new动态分配一个数组,它包含所需的元素数。然而,对于队列操作而言,数组并不太合适。例如,删除数组的第一个元素后,需要将余下的所有元素向前移动一位;否则需要作一些更费力的工作,如将数组视为是循环的。然而,链表能够很好地满足队列的要求。链表由节点序列构成。每一个节点中都包含要保存到链表中的信息以及一个指向下一个节点的指针。对于这里的队列来说,数据部分都是一个"tem 类型的值,因此可以使用下面的结构来表示节点:

	struct Node
	{
		Item item;				// data stored in the node
		struct Node *next;		//pointer to next node
	}
图12.8说明了链表。
如图12.8所示是一个单向链表,因为每个节点都只包含一个指向其他节点的指针。知道第一个节点的地址后,就可以沿指针找到后面的每一个节点。通常,链表最后一个节点中的指针被设置为NULL(或 0),以指出后面没有节点了。在 C++11中,应使用新增的关键字nullptr。要跟踪链表,必须知道第一个节点的地址。可以让 Queue 类的一个数据成员指向链表的起始位置。具体地说,这是所需要的全部信息,有了这种信息后,就可以沿节点链找到任何节点。然而,由于队列总是将新项目添加到队尾,因此包含一个指向最后一个节点的数据成员将非常方便(参见图12.9)。此外,还可以使用数据成员来跟踪队列可存储的最大项目数以及当前的项目数。所以,类声明的私有部分与下面类似:

在这里插入图片描述

在这里插入图片描述


class Queue
{
	//class scope definitions 
	//Node is a nested structure definition local to this class
	struct Node
	{
		Item item;struct Node* next;
	};enum
	{
		Q_SIZE = 10
	};
public:
//...

private:
	Node* front;	//pointer to front of Queue
	Node* rear;		//pointer to rear of Queue
	int items;		//current number of items in queue
	const int qsize;	//maximum number of items in queue
};

12.7.2 Customer类
接下来需要设计客户类。通常,ATM客户有很多属性,例如姓名、账户和账户结余。然而,这里的模拟需要使用的唯一一个属性是客户何时进入队列以及客户交易所需的时间。当模拟生成新客户时,程序将创建一个新的客户对象,并在其中存储客户的到达时间以及一个随机生成的交易时间。当客户到达队首时,程序将记录此时的时间,并将其与进入队列的时间相减,得到客户的等候时间。下面的代码演示了如何定义和实现 Customer 类:

class Customer
{
	private:
		long arrive	//arrival time for customer
		int processtime;//processing time for customer
	public:
		Customer(){arrive = porcesstime = 0;}
		void set(long when);
		long when()const{return arrive;}
		int ptime()const{return processtime;}
};
void Customer::set(long when)
{
	processtime = rand()%3+1;
	arrive=when
}

线分析到这里下篇文章进行具体实现

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值