隊列模板

        基於雙向環形鏈表的隊列模板。
 
注:
        1、環境:vs2005+boost
        2、上一篇的“雙向環形鏈表”構成其基類。
 
==================================================================
#ifndef _QUEUE_H_
#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
==================================================================
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章