头文件:
/*****************************************************************************
* doublelist.h
*
* Double List.
*
* This class template includes a smart pointer supporting "*", "++", "--",
* "==" and "!=" operations, which makes it easy to implement the frequently
* used operations, such as "is empty", "make empty", "begin", "end", "fornt",
* "back", "push front", "push back", "pop front", "pop back", "insert",
* "erase" and so on.
*
* Zhang Ming, 2009-10
*****************************************************************************/
#ifndef DOUBLELIST_H
#define DOUBLELIST_H
#include
namespace itlab
{
/**
* List Node
*/
template
struct Node
{
Type data;
Node *prev;
Node *next;
Node( const Type &d=Type(), Node *p=NULL, Node *n=NULL )
: data(d), prev(p), next(n)
{ }
};
// class Node
/**
* List Iterator
*/
template class DList;
template
class ListItr
{
friend class DList;
public:
ListItr();
ListItr( Node *p );
~ListItr();
inline Type& operator*();
inline const Type& operator*() const;
inline ListItr& operator++();
inline ListItr operator++( int );
inline ListItr& operator--();
inline ListItr operator--( int );
inline bool operator==( const ListItr &rhs ) const;
inline bool operator!=( const ListItr &rhs ) const;
private:
Node *current;
};
// class ListItr
/**
* Double List
*/
template
class DList
{
public:
DList();
DList( const DList &rhs );
~DList();
DList& operator=( const DList &rhs );
typedef ListItr Iterator;
typedef const Iterator Const_Iterator;
inline void clear();
inline bool isEmpty() const;
inline int size() const;
inline Iterator begin();
inline Const_Iterator begin() const;
inline Iterator end();
inline Const_Iterator end() const;
inline Type& front();
inline const Type& front() const;
inline Type& back();
inline const Type& back() const;
inline void pushFront( const Type &x );
inline void pushBack( const Type &x );
inline void popFront();
inline void popBack();
Iterator insert( Iterator itr, const Type &x );
Iterator erase( Iterator itr );
Iterator erase( Iterator start, Iterator end );
private:
int listSize;
Node *head;
Node *tail;
inline void init();
};
// class DList
#include
}
// namespace itlab
#endif
// DOUBLELIST_H
实现文件:
/*****************************************************************************
* doublelist-impl.h
*
* Implementation for ListItr and DList class.
*
* Zhang Ming, 2009-10
*****************************************************************************/
/**
* constructors and destructor
*/
template
ListItr::ListItr()
{
}
template
ListItr::ListItr( Node *p ) : current(p)
{
}
template
ListItr::~ListItr()
{
}
/**
* Overload operations of pointer.
*/
template
inline Type& ListItr::operator*()
{
return current->data;
}
template
inline const Type& ListItr::operator*() const
{
return current->data;
}
/**
* Overload operations of "++" and "--".
*/
template
inline ListItr& ListItr::operator++()
{
current = current->next;
return *this;
}
template
inline ListItr ListItr::operator++( int )
{
ListItr old = *this;
++( *this );
return old;
}
template
inline ListItr& ListItr::operator--()
{
current = current->prev;
return *this;
}
template
inline ListItr ListItr::operator--( int )
{
ListItr old = *this;
--( *this );
return old;
}
/**
* Overload comparison operations.
*/
template
inline bool ListItr::operator==( const ListItr &rhs ) const
{
return current == rhs.current;
}
template
inline bool ListItr::operator!=( const ListItr &rhs ) const
{
return !( *this == rhs );
}
/**
* constructors and destructor
*/
template< typename Type >
inline void DList::init()
{
listSize = 0;
head = new Node;
tail = new Node;
head->next = tail;
tail->prev = head;
}
template< typename Type >
DList::DList()
{
init();
}
template< typename Type >
DList::DList( const DList &rhs )
{
init();
*this = rhs;
}
template< typename Type >
DList::~DList()
{
clear();
delete head;
delete tail;
}
/**
* assigning operator
*/
template< typename Type >
DList& DList::operator=( const DList &rhs )
{
if( this == &rhs )
return *this;
clear();
for( Iterator itr=rhs.begin(); itr!=rhs.end(); ++itr )
pushBack( *itr );
return *this;
}
/**
* Make the list empty.
*/
template< typename Type >
inline void DList::clear()
{
while( !isEmpty() )
popFront();
}
/**
* If the list is empty, return true.
*/
template< typename Type >
inline bool DList::isEmpty() const
{
return size() == 0;
}
/**
* Return the size of list.
*/
template< typename Type >
inline int DList::size() const
{
return listSize;
}
/**
* Get the beginning iterator of the list.
*/
template< typename Type >
inline typename DList::Iterator DList::begin()
{
return Iterator( head->next );
}
template< typename Type >
inline typename DList::Const_Iterator DList::begin() const
{
return Iterator( head->next );
}
/**
* Get the ending iterator of the list.
*/
template< typename Type >
inline typename DList::Iterator DList::end()
{
return Iterator( tail );
}
template< typename Type >
inline typename DList::Const_Iterator DList::end() const
{
return Iterator( tail );
}
/**
* Get the front element of the list.
*/
template< typename Type >
inline Type& DList::front()
{
return *begin();
}
template< typename Type >
inline const Type& DList::front() const
{
return *begin();
}
/**
* Get the back element of the list.
*/
template< typename Type >
inline Type& DList::back()
{
return *--end();
}
template< typename Type >
inline const Type& DList::back() const
{
return *--end();
}
/**
* Push an element from the front of the list.
*/
template< typename Type >
inline void DList::pushFront( const Type &x )
{
insert( begin(), x );
}
/**
* Push an element from the back of the list.
*/
template< typename Type >
inline void DList::pushBack( const Type &x )
{
insert( end(), x );
}
/**
* Pop an element from the front of the list.
*/
template< typename Type >
inline void DList::popFront()
{
erase( begin() );
}
/**
* Push an element from the back of the list.
*/
template< typename Type >
inline void DList::popBack()
{
erase( --end() );
}
/**
* Insert an element into list at the position pointed by "itr".
*/
template< typename Type >
typename DList::Iterator DList::insert( Iterator itr,
const Type &x )
{
Node *p = itr.current;
p->prev = p->prev->next = new Node( x, p->prev, p );
listSize++;
return Iterator( p->prev );
}
/**
* Erase an element pointed by "itr".
*/
template< typename Type >
typename DList::Iterator DList::erase( Iterator itr )
{
Node *p = itr.current;
Iterator tmp( p->next );
p->prev->next = p->next;
p->next->prev = p->prev;
listSize--;
delete p;
return tmp;
}
/**
* Erase elements from "start" to "end" of the list .
*/
template< typename Type >
typename DList::Iterator DList::erase( Iterator start,
Iterator end )
{
for( Iterator itr = start; itr != end; )
itr = erase( itr );
return end;
}
测试文件:
/*****************************************************************************
* dlist_test.cpp
*
* Double list class testing.
*
* Zhang Ming, 2009-10
*****************************************************************************/
#include
#include
#include
using namespace std;
using namespace itlab;
template
void printList( const DList &dl )
{
if( dl.isEmpty() )
cout << " The list is empty!" << endl;
typename DList::Iterator itr = dl.begin();
while( itr != dl.end() )
cout << " " << *itr++ << endl;
cout << endl;
}
int main()
{
string name;
DList dl;
dl.pushBack( "Zhang Ming" );
dl.pushBack( "Zhang Zong" );
printList( dl );
dl.pushFront( "Yu Kai" );
dl.pushFront( "Yu Zong" );
printList( dl );
dl.popFront();
dl.popFront();
printList( dl );
dl.popBack();
printList( dl );
DList::Iterator itr = dl.begin();
dl.insert( itr, "Yu Kai" );
printList( dl );
dl.insert( dl.end(), "Yu Zong" );
printList( dl );
cout << " The first element in the list is: " << dl.front() << endl;
cout << " The last element in the list is: " << dl.back() << endl;
cout << endl;
dl.erase( dl.begin() );
dl.erase( --dl.end() );
printList( dl );
DList::Const_Iterator citr = dl.begin();
cout << " " << *citr << endl;
cout << endl;
dl.clear();
printList( dl );
return 0;
}