从现在开始,我们开始讨论如何实现一些常用的数据结构和其中的一些经典算法.等把数据结构讲完了.我可能会继续讨论VC++的编程只是以及VS平台下的C/C++开发等等.呵呵.我们进入正题吧.
我在这里就只实现线性表的连表结构.当然了,这里实际上包含了好多知识.我希望大家在引用的时候.一定要领悟里面的一些变成思想.和变成风格以及变成技巧.废话不说了.看代码吧.对了,我这里使用模板实现的.
#ifndef _LIST_H_
#define _LIST_H_
#define NULL 0
template <typename T>
class CList;
template <typename T>
struct Elem
{
private:
friend CList<T>;
private:
T elem;
Elem<T> * pNext;
Elem<T> * pFore;
Elem():pNext(NULL),pFore(NULL){};
public:
Elem(T e):elem(e),pNext(NULL),pFore(NULL){};
};
/*-------------------------------------*/
声明:
1、该线性表是基于0的索引
/*-------------------------------------*/
template <typename T>
class CList
{
public:
CList();
CList( const T e );
CList( const CList<T> & l );
virtual ~CList();
public:
/*-------------------------------------*/
插入元素到线性表,返回该元素的索引,
失败返回-1
/*-------------------------------------*/
int Insert ( int pos, const T e );
int Insert ( int pos, const CList<T> & l );
int PushBack ( const T e );
int PushBack ( const CList<T> & l );
/*-------------------------------------*/
在线性表中查找元素,返回第一个匹配元素的
索引,失败返回-1
/*-------------------------------------*/
int Find ( const T e );
int ReverseFind ( const T e );
/*-------------------------------------*/
得到线性表中指定索引的元素,返回元素的索
引,失败返回-1
/*-------------------------------------*/
int GetAt ( T & e, int pos );
/*-------------------------------------*/
给线性表中指定索引的元素赋值,返回元素的
索引,失败返回-1
/*-------------------------------------*/
int SetAt ( const T e, int pos );
/*-------------------------------------*/
其他
/*-------------------------------------*/
bool IsEmpty();
int GetLength();
void DestroyList();
/*-------------------------------------*/
运算符重载
/*-------------------------------------*/
T & operator [] ( int pos );
void operator = ( const T e );
void operator = ( const CList<T> & l );
void operator += ( const T e );
void operator += ( const CList<T> & l);
friend CList<T> & operator + ( const CList<T> & l, const T e );
friend CList<T> & operator + ( const T e ,const CList<T> & l );
friend CList<T> & operator + ( const CList<T> & l1, const CList<T> & l2 );
public:
#ifdef _USE_OUTPUT_
/*-----------------------------------------------*/
如果支持控制台输出,并且想要有输出功能。需要在使用
的地方声明_USE_OUTPUT_宏
/*-----------------------------------------------*/
void Display()
{
Elem<T> * p = NULL;
p = m_pHead ->pNext ;
while( p != m_pTail )
{
//cout << *p ;
cout << p ->elem << "/t" ;
p = p ->pNext;
}
cout << endl;
}
#endif//_USE_OUTPUT_
private:
private:
Elem<T> * m_pHead;
Elem<T> * m_pTail;
int m_nLen;
};
template <typename T>
CList<T>::CList()
{
m_pHead = new Elem<T>();
m_pTail = new Elem<T>();
m_pHead ->pNext = m_pTail;
m_pTail ->pFore = m_pHead;
m_nLen = 0;
}
template <typename T>
CList<T>::CList( const T e )
{
Elem<T> *pElem = new Elem<T>(e);
m_pHead = new Elem<T>();
m_pTail = new Elem<T>();
m_pHead ->pNext = pElem;
pElem ->pFore = m_pHead;
pElem ->pNext = m_pTail;
m_pTail ->pFore = pElem;
}
template <typename T>
CList<T>::CList( const CList<T> & l )
{
Elem<T> *p,*q,*r;
int i;
p = q = r = NULL;
m_pHead = new Elem<T>();
m_pTail = new Elem<T>();
m_pHead ->pNext = m_pTail;
m_pTail ->pFore = m_pHead;
p = m_pTail ->pFore;
q = m_pTail;
r = l.m_pTail ->pFore ;
while( r != l.m_pHead )
{
Elem<T> *pElem = new Elem<T>( r->elem );
p ->pNext = pElem;
pElem ->pFore = p;
pElem ->pNext = q;
q ->pFore = pElem;
q = q ->pFore;
r = r ->pFore;
}
m_nLen = l.m_nLen;
}
template <typename T>
CList<T>::~CList()
{
DestroyList();
delete m_pHead ;
delete m_pTail ;
m_pHead = NULL;
m_pTail = NULL;
m_nLen = 0;
}
template <typename T>
int CList<T>::Insert( int pos, const T e )
{
if ( pos < 0 || pos > m_nLen ) return -1;
Elem<T> *p,*q;
int i;
p = q = NULL;
Elem<T> *pElem = new Elem<T>(e);
if ( pos <= m_nLen / 2 )
{
q = m_pHead;
for( i = 0; i <= pos; i++ )
{
p = q;
q = q ->pNext;
}
p ->pNext = pElem;
pElem ->pFore = p;
pElem ->pNext = q;
q ->pFore = pElem;
}
else
{
q = m_pTail;
for( i = m_nLen; i >= pos; i-- )
{
p = q;
q = q->pFore;
}
p ->pFore = pElem;
pElem ->pNext = p;
pElem ->pFore = q;
q->pNext = pElem;
}
m_nLen++;
return pos;
}
template <typename T>
int CList<T>::Insert( int pos, const CList<T> & l )
{
if ( pos < 0 || pos > m_nLen ) return -1;
Elem<T> *p,*q,*r;
int i;
p = q = NULL;
if ( pos <= m_nLen / 2 )
{
q = m_pHead;
for( i = 0; i <= pos; i++ )
{
p = q;
q = q ->pNext;
}
r = l.m_pTail ->pFore ;
while( r != l.m_pHead )
{
Elem<T> *pElem = new Elem<T>( r->elem );
p ->pNext = pElem;
pElem ->pFore = p;
pElem ->pNext = q;
q ->pFore = pElem;
q = q ->pFore;
r = r ->pFore;
}
}
else
{
q = m_pTail;
for( i = m_nLen; i >= pos; i-- )
{
p = q;
q = q->pFore;
}
r = l.m_pHead ->pNext ;
while( r != l.m_pTail )
{
Elem<T> *pElem = new Elem<T>( r->elem );
p ->pFore = pElem;
pElem ->pNext = p;
pElem ->pFore = q;
q ->pNext = pElem;
q = q ->pNext;
r = r ->pNext;
}
}
m_nLen += l.m_nLen;
return pos;
}
template <typename T>
int CList<T>::PushBack( const T e )
{
Elem<T> * pElem = NULL;
pElem = new Elem<T>(e);
pElem ->pFore = m_pTail ->pFore;
m_pTail ->pFore ->pNext = pElem;
pElem ->pNext = m_pTail;
m_pTail ->pFore = pElem;
m_nLen++;
return m_nLen - 1;
}
template <typename T>
int CList<T>::PushBack( const CList<T> & l )
{
Elem<T> *p,*q,*r;
int i;
p = q = r = NULL;
p = m_pTail ->pFore;
q = m_pTail;
r = l.m_pTail ->pFore ;
while( r != l.m_pHead )
{
Elem<T> *pElem = new Elem<T>( r->elem );
p ->pNext = pElem;
pElem ->pFore = p;
pElem ->pNext = q;
q ->pFore = pElem;
q = q ->pFore;
r = r ->pFore;
}
m_nLen += l.m_nLen;
return m_nLen - 1;
}
template <typename T>
int CList<T>::Find( const T e )
{
Elem<T> *p = NULL;
int nPos = -1;
p = m_pHead ->pNext;
while( p != m_pTail )
{
nPos++;
if( p ->elem == e )
break ;
p = p ->pNext;
}
return nPos;
}
template <typename T>
int CList<T>::ReverseFind( const T e )
{
Elem<T> *p = NULL;
int nPos = -1;
p = m_pTail ->pFore;
while( p != m_pHead )
{
nPos++;
if( p ->elem == e )
break ;
p = p ->pFore;
}
return nPos;
}
template <typename T>
int CList<T>::GetAt( T & e, int pos )
{
if ( pos < 0 || pos >= m_nLen ) return -1;
Elem<T> *p = NULL;
int nPos;
if( pos <= m_nLen / 2 )
{
nPos = 0;
p = m_pHead ->pNext;
while( nPos < pos )
{
nPos++;
p = p ->pNext;
}
e = p ->elem;
}
else
{
nPos = m_nLen - pos - 1;
p = m_pTail ->pFore;
while( nPos > 0 )
{
nPos--;
p = p ->pFore;
}
e = p ->elem;
}
return pos;
}
template <typename T>
int CList<T>::SetAt( const T e, int pos )
{
if ( pos < 0 || pos >= m_nLen ) return -1;
Elem<T> *p = NULL;
int nPos;
if( pos <= m_nLen / 2 )
{
nPos = 0;
p = m_pHead ->pNext;
while( nPos < pos )
{
nPos++;
p = p ->pNext;
}
p ->elem = e;
}
else
{
nPos = m_nLen - pos - 1;
p = m_pTail ->pFore;
while( nPos > 0 )
{
nPos--;
p = p ->pFore;
}
p ->elem = e;
}
return pos;
}
template <typename T>
bool CList<T>::IsEmpty()
{
return m_nLen == 0;
}
template <typename T>
int CList<T>::GetLength()
{
return m_nLen;
}
template <typename T>
void CList<T>::DestroyList()
{
Elem<T> *p, *q;
p = q = NULL;
p = m_pHead ->pNext;
while( p != m_pTail )
{
q = p ->pNext;
delete p;
p = q;
}
m_pHead ->pNext = m_pTail;
m_pTail ->pFore = m_pHead;
m_nLen = 0;
}
template <typename T>
T & CList<T>::operator []( int pos )
{
if ( pos < 0 || pos >= m_nLen ) throw exception("非法索引访问!");
Elem<T> *p = NULL;
int nPos;
if( pos <= m_nLen / 2 )
{
nPos = 0;
p = m_pHead ->pNext;
while( nPos < pos )
{
nPos++;
p = p ->pNext;
}
return p ->elem;
}
else
{
nPos = m_nLen - pos - 1;
p = m_pTail ->pFore;
while( nPos > 0 )
{
nPos--;
p = p ->pFore;
}
return p ->elem;
}
}
template <typename T>
void CList<T>::operator =( const T e )
{
DestroyList( );
PushBack( e );
}
template <typename T>
void CList<T>::operator =( const CList<T> & l )
{
DestroyList( );
PushBack( l );
}
template <typename T>
void CList<T>::operator +=( const T e )
{
PushBack( e );
}
template <typename T>
void CList<T>::operator +=( const CList<T> & l )
{
PushBack( l );
}
template <typename T>
CList<T> & operator +( const CList<T> & l, const T e )
{
CList<T> *pList = new CList<T>(l);
pList->PushBack( e );
return *pList;
}
template <typename T>
CList<T> & operator +( const T e, const CList<T> & l )
{
CList<T> *pList = new CList<T>(e);
pList->PushBack( l );
return *pList;
}
template <typename T>
CList<T> & operator +( const CList<T> & l1, const CList<T> & l2 )
{
CList<T> *pList = new CList<T>(l1);
pList->PushBack( l2 );
return *pList;
}
#endif//_LIST_H_