数据结构之线性表

从现在开始,我们开始讨论如何实现一些常用的数据结构和其中的一些经典算法.等把数据结构讲完了.我可能会继续讨论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_

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值