Queue、StaticQueue、LinkQueue

本文深入探讨了队列数据结构的特性与实现,包括队列的基本概念,静态队列与链式队列的区别,以及它们在不同场景下的应用。重点介绍了静态队列的固定容量与数据拷贝,以及链式队列的动态容量与高效插入删除操作。

队列的知识点

  队列的特点:
    队列只能操纵队头队尾元素
    数据先进先出,(数据在队尾插入,从队头取出)

队列的先进先出
队列的继承结构

Queue

Queue.h

#ifndef __Queue_H_
#define __Queue_H_

#include "Object.h"


namespace JYlib
{

/*
抽象父类 队列(先进先出)
*/
template < typename T >
class Queue : public Object
{
public:
	virtual void add(const T& e) =0;
	virtual void remove() =0;
	virtual T front()const =0;
	virtual void clear() =0;
	virtual int length()const =0;
};



}


#endif

StaticQueue

  StaticQueue的特点:
    队列容量大小固定(通过模板参数确定)
    队列内的数据是拷贝过来的,与原对象无关
    静态队列初始化时,(原生数组)会进行无参构造,数据加入时发生拷贝构造效率低下

#ifndef __StaticQueue_H_
#define __StaaticQueue_H_

#include "Queue.h"
#include "Exception.h"


namespace JYlib
{

/*
顺序队
使用循环队列方式,队列呈环形
出队列后不需要移动队列至0处,仅移动队头标志,效率提高
*/
template < typename T,int N >
class StaticQueue : public Queue<T>
{
protected:
	T m_space[N];
	int m_front;//队头标识
	int m_rear;//队尾标识
	int m_length;//当前队列长度
public:
	StaticQueue()
	{
		m_front = 0;
		m_rear = 0;
		m_length = 0;
	}

	int capacity()const
	{
		return N;
	}

	void add(const T& e)
	{
		if(m_length < N)
		{
			m_space[m_rear] = e;
			m_rear = (m_rear + 1) % N;
			m_length++;
		}
		else
		{
			THROW_EXCEPTION(InvalidParameterException,"NO space in current queue ...");
		}
	}

	void remove()
	{
		if(m_length > 0)
		{
			m_front = (m_front + 1) % N;
			m_length--;
		}
		else
		{
			THROW_EXCEPTION(InvalidOperationException,"NO element in current queue ...");
		}
	}

	T front()const
	{
		if(m_length>0)
		{
			return m_space[m_front];
		}
		else
		{
			THROW_EXCEPTION(InvalidOperationException,"NO element in current queue ...");
		}
	}

	void clear()
	{
		m_front = 0;
		m_rear = 0;
		m_length = 0;
	}

	int length()const
	{
		return m_length;
	}
};



}


#endif

LinkQueue

  链式队的特点:
    队列容量大小可以一直拓展
    组合使用LinuxList(Linux的双向循环链表),插入与删除都无需遍历链表(比单链表效率高)
    队列内的数据是通过链表指针指向的,与原对象有关
    链式队列初始化时,仅仅是初始化链表,与指针指向数据,避免了无参构造以及拷贝构造,效率高

#ifndef __LinkQueue_H_
#define __LinkQueue_H_

#include "include/LinuxList.h"
#include "include/Queue.h"
#include "include/Exception.h"


namespace JYlib
{

/*
链式队
使用LinuxList(双向循环链表)
插入与删除都无需遍历链表,提高效率
*/
template < typename T >
class LinkQueue : public Queue<T>
{
protected:
	struct Node : public Object
	{
		list_head head;
		T value;
	};

	list_head m_header;
	int m_length;
public:
	LinkQueue()
	{
		INIT_LIST_HEAD(&m_header);
		m_length = 0;
	}

	void add(const T& e)//增加至队尾
	{
		Node* new_node = new Node();

		if(new_node != NULL)
		{
			new_node->value = e;

			list_add_tail(&new_node->head,&m_header);

			m_length++;
		}
		else
		{
			THROW_EXCEPTION(NoEnoughMemoryException,"No memory to add new element ...");
		}
	}

	void remove()//移除首元素
	{
		if(m_length > 0)
		{
			list_head* remove = m_header.next;

			list_del(remove);

			m_length--;

			delete list_entry(remove,Node,head);
		}
		else
		{
			THROW_EXCEPTION(InvalidOperationException,"NO element in current queue ...");
		}	
	}

	T front()const//返回队首值
	{
		if(m_length > 0)
		{
			return list_entry(m_header.next,Node,head)->value;
		}
		else
		{
			THROW_EXCEPTION(InvalidOperationException,"NO element in current queue ...");
		}
	}

	void clear()
	{
		while(m_length > 0)
		{
			remove();
		}
	}

	int length()const
	{
		return m_length;
	}

	~LinkQueue()
	{
		clear();
	}
};



}


#endif

#ifndef LINKQUEUE_H #define LINKQUEUE_H #include <string> using namespace std; template <class DataType> struct Node { DataType data; Node<DataType>* next; }; template <class DataType> class LinkQueue { public: LinkQueue(); ~LinkQueue(); void EnQueue(DataType x); DataType DeQueue(); DataType GetQueue(); int Empty(); int Size(); private: Node<DataType>* front; Node<DataType>* rear; }; template <class DataType> LinkQueue<DataType>::LinkQueue() { Node<DataType>* s = new Node<DataType>; s->next = NULL; front = rear = s; } template <class DataType> LinkQueue<DataType>::~LinkQueue() { while (front != NULL) { Node<DataType>* p = front; front = front->next; delete p; } front = rear =NULL; } template <class DataType> void LinkQueue<DataType>::EnQueue(DataType x) { Node<DataType>* s = new Node<DataType>; s->data = x; s->next = NULL; rear->next = s; rear = s; } template <class DataType> DataType LinkQueue<DataType>::DeQueue() { if (front == rear) { throw "下溢"; } Node<DataType>* p = front->next; DataType x = p->data; front->next = p->next; if (p->next == NULL) { rear = front; } delete p; return x; } template <class DataType> DataType LinkQueue<DataType>::GetQueue() { if (front == rear) { throw "队列为空,无法获取队首元素!"; } return front->next->data; } template <class DataType> int LinkQueue<DataType>::Empty() { return front == rear ? 1 : 0; } template <class DataType> int LinkQueue<DataType>::Size() { int count = 0; Node<DataType>* p = front->next; while (p != NULL) { count++; p = p->next; } return count; } #endif #include <iostream> #include <string> #include "LinkQueue.h" using namespace std; int main() { const int M=5; LinkQueue<string> patientQueue; string command; cout << "=== 医院门诊叫号系统 ===" << endl; cout << "支持命令:" << endl; cout << " Name - 患者签到" << endl; cout << " call - 医生叫号" << endl; cout << " front - 查看当前队首患者" << endl; cout << " quit - 退出系统" << endl; while (true){ cout <<"\n请输入命令: "; cin >>command; if (command == "Name") { string name; cin >> name; if (patientQueue.Size() >= M){ cout << "人数限制,请稍后签到!" << endl; } else { patientQueue.EnQueue(name); cout << "患者 [" << name << "] 签到成功,当前候诊人数:" << patientQueue.Size() << endl; } } else if (command == "call") { try { if (patientQueue.Empty()) { cout << "候诊区暂无患者,请稍候!" << endl; } else { string name = patientQueue.DeQueue(); cout << "正在呼叫患者:[" << name << "] 进入诊室。" << endl; cout << "当前候诊人数:" << patientQueue.Size() << endl; } } catch (const char* msg) { cout << msg << endl; } } else if (command == "front") { try { cout << "当前等待的首位患者是:[" << patientQueue.GetQueue() << "]" << endl; } catch (const char* msg) { cout << msg << endl; } } else if (command == "quit") { cout <<"系统退出。" << endl; break; } else { cout <<"无效命令!请重新输入。" << endl; } } return 0; } 假设只有一位医生,在一段时间内随机地来几位病人;假设病人到达的时间间隔为0~14分钟之间的某个随机值,每个病人所需处理时间为1~9分钟之间的某个随机值。试用队列结构进行模拟。 基本要求 : (1)输出每个病人的到达时间、等待时间、看病开始时间和结束时间 (2)输出医生的诊治时间和等待时间 (3)输出医生的总等待时间和病人的平均等待时间。 程序设计思路:计算机模拟事件处理时,程序按模拟环境中的事件出现顺序逐一处理,在本程序中体现为医生逐个为到达病人看病。当一个病人就诊完毕而下一位还未到达时,时间立即推进为下一位病人服务,中间时间为医生空闲时间。当一个病人还未结束之前,另有一位病人到达,则这些病人应依次排队,等候就诊。
最新发布
11-27
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值