雙向鏈表模板

        雙向環形鏈表模板。
 
注:
        1、測試編譯環境:vs2005+boost
        2、使用兩啞頭結點,簡化特殊情況的處理。
 
=====================================================================
 
=====================================================================
#ifndef _LIST_H_
#define _LIST_H_

#include <boost/throw_exception.hpp>

#define EN_TEST_LIST
#ifdef EN_TEST_LIST
#include <boost/lexical_cast.hpp>
#include <iostream>
#include <string>
#endif

namespace redwolf
{
    template <typename T> class clist;
    template <typename T> class cqueue;

    template <typename T>
    class list_node
    {
    public:

    protected:

    private:
  list_node(const T& item=T()):element(item), _p(NULL), _n(NULL){}
  
  T element;
  list_node<T>* _p;
  list_node<T>* _n;
  friend class clist<T>;//環形鏈表
  friend class cqueue<T>;//環形隊列
    };


    //環形鏈表,這裏通過啞節點來避免對於頭結點後尾節點的特殊處理
    template <typename T>
    class clist
    {
    public:
  //構造0  
  clist():_h(new list_node<T>(T())){//no throw
      _h->_n=_h;
      _h->_p=_h;
  }

  //構造1
  clist(const T& item):_h(new list_node<T>(T())){//no throw
      list_node<T>* _temp=new list_node<T>(item);
      if(_temp==NULL) boost::throw_exception("memory unenough.");
      _temp->_p=_h;
      _temp->_n=_h;
      _h->_n=_temp;
      _h->_p=_temp;
  }

  //拷貝構造
  clist(const clist<T>& other):_h(new list_node<T>(T())){
      _h->_n=_h;
      _h->_p=_h;
      copy(other, *this);
  }

  //析構
  virtual ~clist(){
      this->destroy();
  }

  //重載=
  virtual clist<T>& operator= (const clist<T>& rhs)
  {
      if(&rhs!=this)
      {
    this->clean();
    copy(rhs, *this);
      }
      return *this;
  }

  //重載[](僅做右值)
  virtual T& operator[](int index)const{
      return get(index);
  }

  //判斷鏈表是否爲空
  virtual bool empty() const{
      return ((_h==_h->_n)&&(_h==_h->_p));
  }

  //獲取鏈表大小
  virtual int size()const{
      list_node<T>* _p=_h->_n;
      int i=0;
      while(_p!=_h)
      {
    i++;
    _p=_p->_n;
      }
      return i;
  }

  //向鏈表尾添加一個節點
  virtual void push_back(const T& item)
  {
      list_node<T>* _last=_h->_p;
      list_node<T>* _temp=new list_node<T>(item);
      if(_temp==NULL) boost::throw_exception("memory unenough.");
      _temp->_n=_last->_n;
      _temp->_p=_last;
      _last->_n->_p=_temp;
      _last->_n=_temp;
  }

  //向指定的位置插入一個節點
  virtual void insert(int index, const T& item)
  {  
      list_node<T>* _last=_h->_p, *_first=_h->_n;
      int i=0;
      while(_first!=_h)
      {
    if(i==index) break;
    _first=_first->_n;
    i++;
      }
      //if(_first==_h) return;//索引過界,相當於push_back
      list_node<T>* _temp=new list_node<T>(item);
      if(_temp==NULL) boost::throw_exception("memory unenough.");
      _temp->_n=_first;
      _temp->_p=_first->_p;
      _first->_p->_n=_temp;
      _first->_p=_temp;
  }

  //獲取鏈表尾的元素的引用
  virtual T& get_back() const{
    return _h->_p->element;
  }

  //獲取指定位置的元素的引用
  virtual T& get(int index)const{
      list_node<T>* _first=_h->_n, *_last=_h->_p;
      int i=0;
      while(_first!=_h)
      {
    if(i==index) break;
    _first=_first->_n;
    i++;
      }
      return _first->element;//索引過界時返回的是_h->element
  }

  //刪除最後一個元素
  virtual void del_back(){
      if(empty()) return;
    
      list_node<T>* _last=_h->_p;
      _last->_p->_n=_last->_n;
      _last->_n->_p=_last->_p;
      delete _last;
  }

  //刪除指定位置的元素
  virtual void del(int index){
      if(empty()) return;
    
      list_node<T>* _first=_h->_n, *_last=_h->_p;
      int i=0;
      while(_first!=_h)
      {
    if(i==index) break;
    _first=_first->_n;
    i++;
      }
      if(_first==_h) return;//越界
      else
      {
    _first->_p->_n=_first->_n;
    _first->_n->_p=_first->_p;
    delete _first;
      }
  }

  //清空鏈表
  virtual void clean(){
      clean(_h);
  }

  //銷燬鏈表
  virtual void destroy(){
      destroy(_h);
  }

    protected:

  //清空一個鏈表
  virtual void clean(list_node<T>*& head){
      list_node<T>* _self=head, *_p=head;
    
      head=head->_n;
      while(head!=_self)
      {
    _p=head;
    head->_n->_p=_p->_p;
    head->_p->_n=_p->_n;
    head=head->_n;
    delete _p;
      }
  }

  //銷燬一棵鏈表  
  virtual void destroy(list_node<T>*& head)
  {
      clean(head);
      delete head;
      head=NULL;
  }

  //拷貝一個鏈表到另一個空的鏈表
  virtual void copy(const clist<T>& list, clist<T>& newlist){
      const list_node<T> *_p=list._h->_n;
      while(_p!=list._h)
      {
    newlist.push_back(_p->element);
    _p=_p->_n;
      }
  }

  list_node<T>* _h;//(搖擺於以protected方式還是以privite+friend方式)
  
    private:
  //list_node<T>* _h;//head
  //friend class cqueue<T>;
    };

#ifdef EN_TEST_LIST
    void listtest0()
    {
  using namespace std;
  int i=0, j=0, k=0;
  clist<string> lst0, lst1, lst2, lst3, lst4("0"), lst5("1");
  clist<string> lst6(lst5), lst7(lst5);
  for(i=0; i<20; i++)
      lst4.push_back(boost::lexical_cast<string>(i+1));

  for(j=0; j<21; j++)
      cout<<lst4[j]<<endl;
  lst0=lst1=lst2=lst3=lst4;

  lst0.clean();
  for(j=0; j<lst0.size(); j++)
      cout<<lst0[j]<<endl;

  lst1.del_back();
  for(j=0; j<lst1.size(); j++)
      cout<<lst1[j]<<endl;

  lst2.del(0);
  for(j=0; j<lst2.size(); j++)
      cout<<lst2[j]<<endl;


  lst3.del(3);
  for(j=0; j<lst3.size(); j++)
      cout<<lst3[j]<<endl;

  lst5.del(0);
  for(j=0; j<lst5.size(); j++)
      cout<<lst5[j]<<endl;

  lst6.del_back();
  for(j=0; j<lst6.size(); j++)
      cout<<lst6[j]<<endl;

  lst7.insert(0, "7");
  for(j=0; j<lst7.size(); j++)
      cout<<lst7[j]<<endl;

  lst7.insert(0, "8");
  for(j=0; j<lst7.size(); j++)
      cout<<lst7[j]<<endl;

  lst7.insert(1, "9");
  for(j=0; j<lst7.size(); j++)
      cout<<lst7[j]<<endl;

  lst7.insert(lst7.size()-1, "10");
  for(j=0; j<lst7.size(); j++)
      cout<<lst7[j]<<endl;

  lst7.insert(lst7.size(), "11");
  for(j=0; j<lst7.size(); j++)
      cout<<lst7[j]<<endl;

  for(k=0; k<21; k++)
      cout<<lst4.get(k)<<endl;

  cout<<"=================lst7================"<<endl;
  for(i=0; i<lst7.size(); i++)
      cout<<lst7[i]<<endl;
    }
#endif

};

#endif
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章