#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