#define _QUEUE_H_
#include "list.h"
#define EN_TEST_QUEUE
namespace redwolf
{
template <typename T> class queue;
template<typename T>
class queue_node
{
public:
protected:
private:
queue_node(const T& item=T()):element(item), _p(NULL), _n(NULL){}
T element;
queue_node* _p;
queue_node* _n;//考慮到效率,用雙向鏈表
friend class queue<T>;
};
//隊列,從隊尾(trail)進,從隊頭(head)出
template <typename T>
class queue
{
public:
//構造0
queue():_t(NULL), _h(NULL){}
//構造1
queue(const T& item):_t(new queue_node<T>(item)), _h(_t){}//no throw
//拷貝構造
queue(const queue<T>& other):_t(NULL), _h(_t){
queue_node<T>* _null=NULL;
copy(other._t, _null, _t, _h);
}
//析構
virtual ~queue(){
this->destroy();
}
//重載=
virtual queue& operator= (const queue<T>& rhs){
if(this!=&rhs)
{
this->destroy();
queue_node<T>* _null=NULL;
copy(rhs._t, _null, _t, _h);
}
return *this;
}
//向隊列中加入一個元素
virtual void in(const T& item){
queue_node<T>* _temp=new queue_node<T>(item);
if(_temp==NULL) boost::throw_exception("memory unenough.");
if(empty())
{
_h=_temp;
_t=_temp;
}
else
{
_temp->_n=_t;
_t->_p=_temp;
_t=_temp;
}
}
//從隊列中取出一個元素
virtual T out(){
if(empty())
boost::throw_exception("empty queue!");
queue_node<T>* _p=_h;
_h=_h->_p;
if(_h==NULL) _t=_h;//隊列空了
T t=_p->element;
delete _p;
return t;
}
//獲得隊列頭元素的引用
virtual T& head() const {
return _h->element;
}
//獲取隊列的大小
virtual int size() const {
queue_node<T>* _p=_t;
int i=0;
while(_p!=NULL)
{
i++;
_p=_p->_n;
}
return i;
}
//是否是空棧
virtual bool empty() const{
return (_h==NULL);//or (_t==NULL)
}
//合併兩個同類型的棧,a.unite(b)將把b放在a隊列的頭部
virtual void uinte(const queue<T>& other){
if(empty())
{
queue_node<T>* _null=NULL;
copy(other._t, _null, _t, _h);
}
else
copy(other._t, _h, _h->_n, _h);
}
//銷燬棧
virtual void destroy(){
destroy(_t, _h);
}
protected:
//銷燬一個棧,可以用遞歸,但考慮到效率,儘量迴避
virtual void destroy(queue_node<T>*& _trail, queue_node<T>*& _head){
queue_node<T>* _p0=_trail, *_p1=_trail;
while(_p0!=NULL)
{
_p1=_p0->_n;
delete _p0;
_p0=_p1;
}
_trail=NULL;
_head=_trail;
}
//copy一個棧,如何消除這個遞歸呢?
virtual void copy(const queue_node<T>* _trail, queue_node<T>*& pre ,
queue_node<T>*& trail, queue_node<T>*& head){
if(trail!=NULL)
boost::throw_exception("unempty destin queue");
if(_trail->_n!=NULL)
{
queue_node<T>* _temp=new queue_node<T>(_trail->element);
if(_temp==NULL) boost::throw_exception("memory unenough.");
_temp->_p=pre;
if(pre!=NULL) pre->_n=_temp;
trail=_temp;
copy(_trail->_n, trail, trail->_n, head);
}
else
{
queue_node<T>* _temp=new queue_node<T>(_trail->element);
if(_temp==NULL) boost::throw_exception("memory unenough.");
_temp->_p=pre;
if(pre!=NULL) pre->_n=_temp;
trail=_temp;
head=trail;//if(_trail->_n==NULL) head=trail;
}
}
private:
queue_node<T>* _h;//headu4
queue_node<T>* _t;//trail
};
//環形隊列,基於雙向環形鏈表的隊列(搖擺於繼承list<T>還是成員變量)
template <typename T>
class cqueue : public clist<T>
{
public:
//構造0
cqueue():clist<T>(){}
//構造1
cqueue(const T& item):clist<T>(item){}//no throw
//拷貝構造
cqueue(const queue<T>& other):clist<T>(other){}
//析構
virtual ~cqueue(){}
//重載=
virtual cqueue& operator= (const cqueue<T>& rhs){
if(this!=&rhs)
{
clist<T>::clean();
clist<T>::copy(rhs, *this);
}
return *this;
}
//向隊列中加入一個元素
virtual void in(const T& item){
clist<T>::push_back(item);
}
//從隊列中取出一個元素
virtual T out(){
T t=clist<T>::get(0);
clist<T>::del(0);
return t;
}
//獲得隊列頭元素的引用
virtual T& head() const {
return clist<T>::get(0);
}
//獲取隊列的大小
virtual int size() const {
return clist<T>::size();
}
//是否是空隊列
virtual bool empty() const{
return clist<T>::empty();
}
//合併兩個同類型的隊列,a.unite(b)將把b放在a隊列的頭部
virtual void uinte(const cqueue<T>& other){
if(empty()) return;
list_node<T>* _p=other._h->_n;
while(_p!=other._h)
{
clist<T>::push_back(_p->element);
_p=_p->_n;
}
}
//清空隊列
virtual void clean(){
clist<T>::clean();
}
//銷燬隊列
virtual void destroy(){
clist<T>::destroy();
}
protected:
private:
};
#ifdef EN_TEST_QUEUE
void queuetest0()
{
using namespace std;
#if 0
cout<<endl;
cout<<"=====================queue===================="<<endl;
cout<<endl;
queue<string> s0,s1,s2,s3,s4,s5;
queue<string> s6("redwolf");
s0=s1=s2=s3=s4=s5=s6;
cout<<s0.out()<<endl;
cout<<s0.empty()<<endl;
cout<<s1.head()<<endl;
cout<<s1.empty()<<endl;
s0.in("http");
s0.in("ftp");
s0.in("rtsp");
cout<<s0.size()<<endl;
int cnt=s0.size();
/*for(int i=0; i<cnt; i++)
{
cout<<"head: "<<s0.head()<<endl;
cout<<"out: "<<s0.out()<<endl;
}*/
s1.in("yuxiongjian");
s1.in("study");
s1.in("std...boost");
s0.uinte(s1);
cout<<s0.size()<<endl;
cnt=s0.size();
/*for(int i=0; i<cnt; i++)
{
cout<<"head: "<<s0.head()<<endl;
cout<<"out: "<<s0.out()<<endl;
}*/
s1.uinte(s0);
queue<string> s7(s1);
cout<<s1.size()<<endl;
cnt=s7.size();
queue<string> s8=s7;
for(int i=0; i<cnt; i++)
{
cout<<"head: "<<s7.head()<<endl;
cout<<"out: "<<s7.out()<<endl;
}
s2.size();
s2=s1;
s2.size();
s8.size();
cnt=s8.size();
for(int i=0; i<cnt; i++)
{
cout<<"head: "<<s8.head()<<endl;
cout<<"out: "<<s8.out()<<endl;
}
#else
cout<<endl;
cout<<"=====================cqueue===================="<<endl;
cout<<endl;
cqueue<string> s0,s1,s2,s3,s4,s5;
cqueue<string> s6("redwolf");
s0=s1=s2=s3=s4=s5=s6;
cout<<s0.out()<<endl;
cout<<s0.empty()<<endl;
cout<<s1.head()<<endl;
cout<<s1.empty()<<endl;
s0.in("http");
s0.in("ftp");
s0.in("rtsp");
cout<<s0.size()<<endl;
int cnt=s0.size();
/*for(int i=0; i<cnt; i++)
{
cout<<"head: "<<s0.head()<<endl;
cout<<"out: "<<s0.out()<<endl;
}*/
s1.in("yuxiongjian");
s1.in("study");
s1.in("std...boost");
s0.uinte(s1);
cout<<s0.size()<<endl;
cnt=s0.size();
/*for(int i=0; i<cnt; i++)
{
cout<<"head: "<<s0.head()<<endl;
cout<<"out: "<<s0.out()<<endl;
}*/
s1.uinte(s0);
cqueue<string> s7(s1);
cout<<s1.size()<<endl;
cnt=s7.size();
cqueue<string> s8=s7;
for(int i=0; i<cnt; i++)
{
cout<<"head: "<<s7.head()<<endl;
cout<<"out: "<<s7.out()<<endl;
}
s2.size();
s2=s1;
s2.size();
s8.size();
cnt=s8.size();
for(int i=0; i<cnt; i++)
{
cout<<"head: "<<s8.head()<<endl;
cout<<"out: "<<s8.out()<<endl;
}
#endif
}
#endif
};
#endif