队列(queue)之基础实现

         队列类似于人员排队。首先加入列队的人最先得到服务,并第一个离队,队列项在队尾(back或rear)加入,从对头(front)离队。队列的操作只发生在两端,这使得队列具有先进后出(first-in first-out简写为FIFO)的特性,相对而言,可认为栈只有一端。因为所有的操作都在栈顶执行。这使得栈具有后进先出的特性。

以下是对的几个实现:

1、queue的异常处理类:

#ifndef QUEUE_EXCEPTION_H_
#define QUEUE_EXCEPTION_H_
#include<stdexcept>
#include<string>
using namespace std;
class queueException:public logic_error
{
	public:
		queueException(const string &message="")
			:logic_error(message.c_str())
		{}
};
#endif

 

2、基于指针的队列的实现:

#ifndef QUEUE_POINTER_H_
#define QUEUE_POINTER_H_
#include<string>
#include"queue_exception.h"
template<class T>
class Queue
{
	public:
		//constructor and destructor
		Queue();
		Queue(const Queue &aqueue);
		~Queue();
		//operation functions
		bool isEmpty()const;
		//Detemines whether a queue is empty
		//precondition :None
		//postcondition :returns true if the queue is 
		//empty otherwise returns false
		void enqueue(T newitem)throw(queueException);
		//insert an item at the back of the queue
		//precondition :newitem is the item to be inserted
		//postcondition :if the insertion was successfull
		//newitem is at the back of the queue
		//Exception :throw queueException if newitem cannot 
		//be placed on the queue

		void dequeue()throw(queueException);
		//delete an item at the first of the queue
		//precondition:none
		//postcondition :if the queue is not empty, the item
		//that was added to the queue earlist is delete
		//exception :throws queueexception if the queue if
		//empty

		void dequeue(T & queueFront)throw(queueException);
		//retrieve and delete the front of a queue
		//precondition :none
		//postcondition :if the queue is not empty
		//queueFront contains the items that was 
		//added first and the is deleted
		//exception:throw queueexception if the queue is empty

		void getFront(T &queueFront)const throw(queueException);
		//retrieve the item at the front of a queue
		//precondition :none
		//postcondition :if the queue is not empty
		//queufront contains the item that was added to the queue
		//earlist Exception:throw queueexception if the queue
		//is empty;
	private:
		//the queue is implemented as a linked list
		//with one external pointer to the front and
		//a second pointer to the back of the queue.
		struct Node
		{
			T  items;
			Node *next;
		};
		Node *frontPtr;
		Node *backPtr;
};
#endif

 

#include"queue_pointer.h"
#include<cstddef>
#include<cassert>
template<class T>
Queue<T>::Queue()
{
}
template<class T>
Queue<T>::Queue(const Queue &aqueue)
{
	if(aqueue.frontPtr==NULL)
		frontPtr=backPtr=NULL;
	else
	{
		Node *newPtr= new Node;
		assert(newPtr!=NULL);
		Node *originPtr=aqueue.frontPtr;
		newPtr->items=originPtr->item;
		newPtr->next=NULL;
		frontPtr=newPtr;
		originPtr=originPtr->next;
		while(originPtr!=aqueue.backPtr)
		{
			newPtr->next=new Node;
			assert(newPtr!=NULL);
			newPtr=newPtr->next;
			newPtr->items=originPtr->items;
			newPtr->next=NULL;
			originPtr=originPtr->next;
		}
		backPtr=new Node;
		assert(backPtr!=NULL);
		backPtr->items=originPtr->items;
		backPtr->next=NULL;
	}
}
template<class T>
Queue<T>::~Queue()
{
	while(frontPtr!=NULL)
		dequeue();
	assert((frontPtr==NULL)&&(backPtr==NULL));
}
template<class T>
bool Queue<T>::isEmpty()const
{
	return backPtr==NULL;
}
template<class T>
void Queue<T>::enqueue(T newitem)throw(queueException)
{
	Node *newPtr=new Node;
	if(newPtr==NULL)
		throw queueException("queueException :insert new item faild !");
	else{
	
		newPtr->items=newitem;
		newPtr->next=NULL;
		backPtr->next=newPtr;
		backPtr=newPtr;
	}
}
template<class T>
void Queue<T>::dequeue()throw(queueException)
{
	if(isEmpty())
		throw queueException("queueException :delete the front item failed !");
	else
	{
		Node *temp=frontPtr;
		frontPtr=frontPtr->next;
		temp->next=NULL;
		delete temp;
	}
}
template<class T>
void Queue<T>::dequeue(T &queueFront)throw(queueException)
{
	if(isEmpty())
		throw queueException("queueException :delete the front items failed !");
	else
	{
		Node *temp=frontPtr;
		frontPtr=frontPtr->next;
		queueFront=temp->items;
		temp->next=NULL;
		delete temp;
	}
}
template<class T>
void Queue<T>::getFront(T &queueFront)const throw(queueException)
{
	if(isEmpty())
		throw queueException("queueException :get front items failed !");
	else
	{
		queueFront=frontPtr->items;
	}
}


3、基于数组的队列的实现:

将数组看作为一个环形空间,通过在数组中顺时针移动front 和back 前移队列索引front(删除数据项)和back(插入数据项)。当front或back前移超过MAX-QUEUE-1 时,将返回0,从而消除了前面的实现中的右移的问题,因为循环数组不存在终点。在这种方案中唯一的困难是检测对空和队满的条件,似乎将“front 比back超前一个空间”作为对空的条件,这似乎说明:当队列变空时,front将超前back。只不过这个条件也可能指示一个队列已满。为此这里用了三种方法已标记队列的状态。

为初始化队列,将front设置为0,将back设置为MAX-QUEUE-1,在增加back和front时使用模运算(back=(back+1)%MAX-QUEUE),即可取得循环队列的返回效果。

1)设置一个int 成员变量count ,用于指示队列的项数。

#ifndef QUEUE_ARRAY1_H_
#define QUEUE_ARRAY1_H_
#include"queue_exception.h"
const int MAX=20;
template<class T>
class Queue
{
	public:
		//constructor
		Queue();
		//operation functions
		bool isEmpty()const;
		//detemines whether the queue is empty
		void enqueue(T newitem)throw(queueException);
		//insert an item in the back of the queue if the
		//queue is not full
		void dequeue()throw(queueException);
		//delete an item in the front of the queue if
		//queue is not empty
		void dequeue(T &queueFront)throw(queueException);
		//delete an item in the front of the queue if the 
		//queue is not empty and queueFront contains the value
		//that was being delete
		void getFront(T &queueFront)const throw(queueException);
		//retrieve the queue and queueFront contains the 
		//value of the front items;
	private:
		T items[MAX];
		int size;
		int front;
		int back;

};
#endif

 

#include"queue_array1.h"
template<class T>
Queue<T>::Queue()
{
	size=0;
	front=0;
	back=MAX-1;
}
template<class T>
bool Queue<T>::isEmpty()const
{
	return size==0;
}
template<class T>
void Queue<T>::enqueue(T newitem)throw(queueException)
{
	if(size==MAX)
		throw queueException("queueException :insert new itesm failed !");
	else{
	back=(back+1)%MAX;
	items[back]=newitem;
	size++;
	}
}
template<class T>
void Queue<T>::dequeue()throw(queueException)
{
	if(isEmpty())
		throw queueException("queueException :delete the froont  item failed !");
	else
	{
		front=(front+1)%MAX;
		size--;
	}
}
template<class T>
void Queue<T>::dequeue(T &queueFront)throw(queueException)
{
	if(isEmpty())
		throw queueException("queueException :delete the front item failed !");
	else
	{
		queueFront=items[front];
		front=(front+1)%MAX;
		size--;
	}
}
template<class T>
void Queue<T>::getFront(T &queueFront)const throw(queueException)
{
	if(isEmpty())
		throw queueException("queueException :get the front item failed !");
	else
	{
		queueFront=items[front];
	}
}


2)设置一个bool 类型的变量isFull,当未满时为false,否则为true

 

#ifndef QUEUE_ARRAY2_H_
#define QUEUE_ARRAY2_H_
#include"queue_exception.h"
const int MAX=20;
template<class T>
class Queue
{
	public:
		Queue();

		bool isEmpty()const;
		void enqueue(T newitem)throw(queueException);
		void dequeue()throw(queueException);
		void dequeue(T &queueFront)throw(queueException);
		void getFront(T &queueFront)const throw(queueException);
	private:
		T items[MAX];
		int back;
		int front;
		bool isFull;
};
#endif

 

#include"queue_array2.h"
template<class T>
Queue<T>::Queue()
{
	isFull=false;
	front=0;
	back=MAX-1;
}
template<class T>
bool Queue<T>::isEmpty()const
{
	return ((front==(back+1)%MAX)&&!isFull);
}
template<class T>
void Queue<T>::enqueue(T newitem)throw(queueException)
{
	if(isFull)
		throw queueException("insert new item in the queue failed !");
	else
	{
		back=(back+1)%MAX;
		items[back]=newitem;
		if(front==(back+1)%MAX)
			isFull=true;
	}
}
template<class T>
void Queue<T>::dequeue( )throw(queueException)
{
	if((front==(back+1)%MAX)&&!isFull)
		throw queueException("delete  item in the queue failed !");
	else
	{
		if(isFull)
         		isFull=false;
		front=(front+1)%MAX;
	
	}
}
template<class T>
void Queue<T>::dequeue(T &queueFront)throw(queueException)
{
	if((front==(back+1)%MAX)&&!isFull)
		throw queueException("delete item in the queue failed !");
	else
	{
		if(isFull)
			isFull=false;
		queueFront=items[front];
		front=(front+1)%MAX;
	}
}
template<class T>
void Queue<T>::getFront(T & queueFront)const throw(queueException)
{
	if((front==(back+1)%MAX)&&!isFull)
		throw queueException("get front item failed !");
	else
	{
		queueFront=items[front];
	}
}


3)为数组声明MAX-QUEUE+1个位置,但只使用其中的MAX-QUEUE个位置,剩下的一个数组位置,使front成为对头之前位置的索引。

#ifndef QUEUE_ARRAY3_H_
#define QUEUE_ARRAY3_H_
#include"queue_exception.h"
const int MAX=21;
template<class T>
class Queue
{
	public:
		Queue();
		bool isEmpty()const;
		void enqueue(T newitem)throw(queueException);
		void dequeue()throw(queueException);
		void dequeue(T &queueFront)throw(queueException);
		void getFront(T &queueFront)const throw(queueException);
	private:
		T items[MAX];
		int front;
		int back;
};
#endif


 

#include"queue_array3.h"
template<class T>
Queue<T>::Queue()
{
	front=0;
	back=MAX-1;
}
template<class T>
bool Queue<T>::isEmpty()const
{
	return front==((back+1)%MAX);
}
template<class T>
void Queue<T>::enqueue(T newitem)throw(queueException)
{
	if(front==back)
		throw queueException("queueException :insert new item failed !");
	else
	{
		back=(back+1)%MAX;
		items[back]=newitem;

	}
}
template<class T>
void Queue<T>::dequeue( )throw(queueException)
{
	if(front==(back+1)%MAX)
		throw queueException("queueException :delete the item failed !");
	else
	{
		front=(front+1)%MAX;
	}
}
template<class T>
void Queue<T>::dequeue(T &queueFront)throw(queueException)
{
	if(front==(back+1)%MAX)
		throw queueException("queueException :delete the item failed !");
	else
	{
		front=(front+1)%MAX;
		queueFront=items[(front+1)%MAX];
	}
}
template<class T>
void Queue<T>::getFront(T &queueFront)const throw(queueException)
{
	if(front==(back+1)%MAX)
		throw queueException("queueException :get front item failed!");
	else
	{
		queueFront=items[(front+1)%MAX];
	}
}

这个实现没有维护计数器和标志的开销,但运行的时间更少,对于标准数据类型,该实现所需的空间与需要维护计算器或标志的实现相同,但对于比较复杂的数据,在额外数组位置上浪费的内存会非常大。


3、基于ADT的队列的实现:

#ifndef QUEUE_ADT_H_
#define QUEUE_ADT_H_
#include<list>
#include"queue_exception.h"
using namespace std;
template<class T>
class Queue
{
	public:
		Queue();
		bool isEmpty()const;
		void enqueue(T newitem)throw(queueException);
		void dequeue()throw(queueException);
		void dequeue(T &queueFront)throw(queueException);
		void getFront(T &queueFront)const throw(queueException);
	private:
		list<T> alist;
};
#endif

 

#include"queue_adt.h"
template<class T>
Queue<T>::Queue()
{
}
template<class T>
bool Queue<T>::isEmpty()const
{
	return (alist.empty());
}
template<class T>
void Queue<T>::enqueue(T newitem)throw(queueException)
{
	try{
		alist.insert(alist.size()+1,newitem);
	}
	catch(...)
	{
		throw queueException("queueException :insert new item failed !");
	}
}
template<class T>
void Queue<T>::dequeue()throw(queueException)
{
	try{
		alist.remove(1);
	}catch(...)
	{
		throw queueException("queueException :delete the front item failed !");
	}
}
template<class T>
void Queue<T>::dequeue(T &queueFront) throw(queueException)
{
	try{
		queueFront=alist.retrieve(1);
		alist.remove(1);
	}catch(...)
	{
		throw queueException("queueException :delete the item failed !");
	}
}
template<class T>
void Queue<T>::getFront(T &queueFront)const throw(queueException)
{
	try{
		queueFront=alist.retrieve(1);
	}catch(...)
	{
		throw queueException("queueException : get the front item failed !");
	}
}




 

你可能感兴趣的:(exception,String,null,delete,insert)