+ -
当前位置:首页 → 问答吧 → 最近利用空余时间写了一个链表类,各位朋友给点意见,代码如下:

最近利用空余时间写了一个链表类,各位朋友给点意见,代码如下:

时间:2011-12-03

来源:互联网

C/C++ code
#ifndef CTEMPALTELIST_H
#define CTEMPALTELIST_H
#include <assert.h>
#define NULL 0
template<class T>
class CTempalteList
{
       typedef struct LIST
        {
            T   Data;
            struct LIST* Next;
        }CList;

 public:
        CTempalteList();

        virtual ~CTempalteList();
 protected:
 private:
    CList*          m_Head;//
    CList*          m_EndList;//末尾元素
    unsigned int    m_Count;//计数
public:
    void                  Add(const T Data);//加入元素
    const T               GetAt(const unsigned int Index);//通过索引得到该节点的值
    const unsigned int    GetSize();//获取链表的大小
    T                     operator[](const unsigned int Index);//重载[]运算符
   CTempalteList<T>*      operator+(CTempalteList& Elem);//连接两个链表得到新的链表
    void                  operator=(CTempalteList* List);
    void                  Remove();//删除所有的元素
    void                  Remove(const unsigned int Index);//删除指定位置的值
    int                   Insert(const unsigned int Index,T NewData);//在指定位置插入一个值,返回为链表插入后的长度,如果插入失败则返回为原来的长度否则为新的长度
    int                   Insert(const unsigned int Index,CTempalteList *catList);//在指定位置插入一个值,返回为链表插入后的长度,如果插入失败则返回为原来的长度否则为新的长度

private:
    inline   CList*         GetDataList(const unsigned int Index);
    inline   void           RemoveSTATICELEM();//删除临时拷贝变量
    CTempalteList*          STATICELEM;//用于copy的临时变量
};
template<class T>
typename CTempalteList<T>::CList*  CTempalteList<T>::GetDataList(const unsigned int Index)
{
    CList* Elem=m_Head;
    for(int i=0;i<m_Count;i++)
    {
        if(i==Index)break;
        Elem=Elem->Next;
    }
    return Elem;
}
template<class T>
void CTempalteList<T>::RemoveSTATICELEM()
{
    if(STATICELEM)
    {
        delete STATICELEM;
        STATICELEM=NULL;
    }
}
#endif // CTEMPALTELIST_H

C/C++ code
#include "F:\workspace\CTempalteList\include\\CTempalteList.h"
#include <iostream>
using namespace std;
template<class T>
CTempalteList<T>::CTempalteList()
{
    m_Head=NULL;
    m_Count=0;
    STATICELEM=NULL;
    m_EndList=NULL;
    //ctor
}
template<class T>
CTempalteList<T>::~CTempalteList()
{    //dtor
    Remove();
    RemoveSTATICELEM();//检查是否有临时变量如有则释放内存
}
template<class T>
void CTempalteList<T>::Add(const T Data)
{
    CList* Elem=new CList();
    Elem->Data=Data;
    Elem->Next=NULL;
    if(m_Head==NULL&&m_EndList==NULL)
    {
        m_EndList=m_Head=Elem;
    }
   m_EndList=m_EndList->Next=Elem;
    m_Count++;
}
template<class T>
const T CTempalteList<T>::GetAt(const unsigned int Index)
{
    assert(Index>=0&&Index<m_Count);
    if(Index<0||Index>=m_Count)return NULL;
    return GetDataList(Index)->Data;
}
template<class T>
const unsigned int CTempalteList<T>::GetSize()
{
    return m_Count;
}
template<class T>
T  CTempalteList<T>::operator[](const unsigned int Index)
{
    assert(Index>=0&&Index<m_Count);
    if(Index<0||Index>=m_Count)return NULL;
    return GetDataList(Index)->Data;
}
template<class T>
CTempalteList<T>* CTempalteList<T>::operator+(CTempalteList& Elem)
{
   RemoveSTATICELEM();
   STATICELEM=new CTempalteList();
   for(int i=0;i<m_Count;i++)
    STATICELEM->Add(GetAt(i));
    for(int i=0;i<Elem.GetSize ();i++)
    {
        STATICELEM->Add(Elem[i]);
    }
    return this;
}
template<class T>
void CTempalteList<T>::operator=(CTempalteList<T>* List)
{
    if(List!=NULL&&List->STATICELEM!=NULL)
    {
       for(int i=0;i<List->STATICELEM->GetSize();i++)
        {
            Add(List->STATICELEM->GetAt(i));
        }
            delete List->STATICELEM;
            List->STATICELEM=NULL;
    }


}

template<class T>
void CTempalteList<T>::Remove()
{
    if(m_Head!=NULL)
    {
        CList* NextList=NULL;
        for(int i=0;i<m_Count;i++)
        {
            NextList=m_Head->Next;
            delete m_Head;
            m_Head=NextList;
        }
        m_Head=NULL;
        m_Count=0;
    }
}
template<class T>
void CTempalteList<T>::Remove(const unsigned int Index)
{
    assert(Index>=0&&Index<m_Count);
    if(Index<0||Index>=m_Count)return;
    if(Index==0)
    {
        CList* NextList=m_Head->Next;
        delete m_Head;
        m_Head=NextList;
    }
    else
    {
        CList* PreList=GetDataList(Index-1);//得到前一个元素的指针
        CList* NextList=PreList->Next->Next;
        if(PreList->Next==m_EndList)m_EndList=PreList;//防止删除最后一个指针时还能访问
        delete PreList->Next;
        PreList->Next=NextList;
    }
    m_Count--;
}
template<class T>
int CTempalteList<T>::Insert(const unsigned int Index,T NewData)
{
    assert(Index>=0&&Index<m_Count);
    if(Index<0||Index>=m_Count)return m_Count;
    CList* NewList=new CList();
    NewList->Data=NewData;
    if(Index==0)
    {
        NewList->Next=m_Head;
        m_Head=NewList;
    }
    else
    {
        CList* PreList=GetDataList(Index-1);//得到前一个元素的指针
        NewList->Next=PreList->Next;
        PreList->Next=NewList;
    }
     m_Count++;
     return m_Count;
}
template<class T>
int CTempalteList<T>::Insert(const unsigned int Index,CTempalteList *catList)
{
    assert(Index>=0&&Index<m_Count);
    if(Index<0||Index>=m_Count)return m_Count;
    const int Size=catList->GetSize();
     CList* oldEndList=GetDataList(m_Count-1);//记录插入前最后元素的指针
     //先将待插入的元素全部插入链表后面
    for(int i=0;i< Size;i++)
    {
        Add(catList->GetAt(i));
    }
    CList* NewStartList=oldEndList->Next;//记录新插入元素的头指针
    CList* NewEndList=GetDataList(m_Count-1);//记录插入后最后元素的指针
    oldEndList->Next=NULL;//将新增的链表暂时与旧表断开
    if(Index==0)
    {
        NewEndList->Next=m_Head;
        m_Head=NewStartList;
    }
    else
    {
        CList* InertList=GetDataList(Index-1);
        NewEndList->Next=InertList->Next;
        InertList->Next=NewStartList;
    }
}
int main(void)
{
    CTempalteList<int> list;
    for(int i=0;i<5;i++)
        list.Add(i);
        list.Remove(4);
        list.Add(200);
        for(int i=0;i<list.GetSize();i++)
        cout<<list.GetAt(i)<<" ";
    return 0;
}


我想根据各位的意见进行修改,意见如:执行效率,使用是否方便,代码简洁方面等等。

作者: w378567402   发布时间: 2011-12-03

坐等意见。。。。。

作者: w378567402   发布时间: 2011-12-03

参考 std::list;
不多说了。。。。

作者: mingliang1212   发布时间: 2011-12-03

可以分离编译么。

作者: qq120848369   发布时间: 2011-12-03

可以啊。。。。。。。。。。。。

作者: w378567402   发布时间: 2011-12-03

你完全没必要在你类内部搞一个CTempalteList* STATICELEM;//用于copy的临时变量
你完全可以什么用到什么时候声明,你这样在类内部一直保存导致你的对象体积变大,而且你释放的时候还很容易出错

作者: qscool1987   发布时间: 2011-12-04

恩我也觉得这个地方设计的不太好,我再想想

作者: w378567402   发布时间: 2011-12-04

感觉不错
 

作者: hbysjw   发布时间: 2011-12-04

今天又修改了一下如下
#ifndef CTEMPALTELIST_H
#define CTEMPALTELIST_H
#include <assert.h>
#define NULL 0
#include <iostream>
using namespace std;

template<class T>
class CTempalteList
{
  typedef struct LIST
  {
  T Data;
  struct LIST* Next;
  }CList;

 public:
  CTempalteList();
  CTempalteList(const CTempalteList& List);
  virtual ~CTempalteList();
 protected:
 private:
  CList* m_Head;//头
  CList* m_EndList;//末尾元素
  unsigned int m_Count;//计数
public:
  void Add(const T Data);//加入元素
  const T GetAt(const unsigned int Index)const;//通过索引得到该节点的值
  const unsigned int GetSize()const;//获取链表的大小
  T operator[](const unsigned int Index)const;//重载[]运算符
  friend const CTempalteList<T> operator+( const CTempalteList<T>& Elem1, const CTempalteList<T>& Elem2)//连接两个链表得到新的链表
  {
  CTempalteList<T> List;
  for(int i=0;i<Elem1.m_Count;i++)
  {
  List.Add(Elem1.GetAt(i));
  }
  for(int i=0;i<Elem2.m_Count;i++)
  {
  List.Add(Elem2.GetAt(i));
  }
  return List;
  }
  void operator=(const CTempalteList& List);
  void Remove();//删除所有的元素
  void Remove(const unsigned int Index);//删除指定位置的值
  int Insert(const unsigned int Index,T NewData);//在指定位置插入一个值,返回为链表插入后的长度,如果插入失败则返回为原来的长度否则为新的长度
  int Insert(const unsigned int Index,CTempalteList *catList);//在指定位置插入一个值,返回为链表插入后的长度,如果插入失败则返回为原来的长度否则为新的长度
  int SetAt(const unsigned int Index,T Data);//修改指定位置的数据
private:
  inline CList* GetDataList(const unsigned int Index)const;
};
template<class T>
typename CTempalteList<T>::CList* CTempalteList<T>::GetDataList(const unsigned int Index)const
{
  CList* Elem=m_Head;
  for(int i=0;i<m_Count;i++)
  {
  if(i==Index)break;
  Elem=Elem->Next;
  }
  return Elem;
}


#endif // CTEMPALTELIST_H

#include "F:\workspace\CTempalteList\include\\CTempalteList.h"

template<class T>
CTempalteList<T>::CTempalteList()
{
  m_Head=NULL;
  m_Count=0;
  m_EndList=NULL;
  //ctor
}
template<class T>
CTempalteList<T>::CTempalteList(const CTempalteList& List)
{
  m_Head=NULL;
  m_Count=0;
  m_EndList=NULL;
  for(int i=0;i<List.m_Count;i++)
  Add(List.GetAt(i));
}
template<class T>
CTempalteList<T>::~CTempalteList()
{ //dtor
  Remove();
}
template<class T>
void CTempalteList<T>::Add(const T Data)
{
  CList* Elem=new CList();
  Elem->Data=Data;
  Elem->Next=NULL;
  if(m_Head==NULL&&m_EndList==NULL)
  {
  m_EndList=m_Head=Elem;
  }
  m_EndList=m_EndList->Next=Elem;
  m_Count++;
}
template<class T>
const T CTempalteList<T>::GetAt(const unsigned int Index) const
{
  assert(Index>=0&&Index<m_Count);
  if(Index<0||Index>=m_Count)return NULL;
  return GetDataList(Index)->Data;
}
template<class T>
const unsigned int CTempalteList<T>::GetSize()const
{
  return m_Count;
}
template<class T>
T CTempalteList<T>::operator[](const unsigned int Index)const
{
  assert(Index>=0&&Index<m_Count);
  if(Index<0||Index>=m_Count)return NULL;
  return GetDataList(Index)->Data;
}


template<class T>
void CTempalteList<T>::operator=(const CTempalteList<T>& List)
{
  if(List.m_Head!=NULL)
  {
  Remove();
  for(int i=0;i<List.m_Count;i++)
  Add(List.GetAt(i));

  }
  // return *this;
}

template<class T>
void CTempalteList<T>::Remove()
{
  if(m_Head!=NULL)
  {
  CList* NextList=NULL;
  for(int i=0;i<m_Count;i++)
  {
  NextList=m_Head->Next;
  delete m_Head;
  m_Head=NextList;
  }
  m_Head=NULL;
  m_Count=0;
  m_EndList=NULL;
  }
}
template<class T>
void CTempalteList<T>::Remove(const unsigned int Index)
{
  assert(Index>=0&&Index<m_Count);
  if(Index<0||Index>=m_Count)return;
  if(Index==0)
  {
  CList* NextList=m_Head->Next;
  delete m_Head;
  m_Head=NextList;
  }
  else
  {
  CList* PreList=GetDataList(Index-1);//得到前一个元素的指针
  CList* NextList=PreList->Next->Next;
  if(PreList->Next==m_EndList)m_EndList=PreList;//防止删除最后一个指针时还能访问
  delete PreList->Next;
  PreList->Next=NextList;
  }
  m_Count--;
}
template<class T>
int CTempalteList<T>::Insert(const unsigned int Index,T NewData)
{
  assert(Index>=0&&Index<m_Count);
  if(Index<0||Index>=m_Count)return m_Count;
  CList* NewList=new CList();
  NewList->Data=NewData;
  if(Index==0)
  {
  NewList->Next=m_Head;
  m_Head=NewList;
  }
  else
  {
  CList* PreList=GetDataList(Index-1);//得到前一个元素的指针
  NewList->Next=PreList->Next;
  PreList->Next=NewList;
  }
  m_Count++;
  return m_Count;
}
template<class T>
int CTempalteList<T>::Insert(const unsigned int Index,CTempalteList *catList)
{
  assert(Index>=0&&Index<m_Count);
  if(Index<0||Index>=m_Count)return m_Count;
  const int Size=catList->GetSize();
  CList* oldEndList=GetDataList(m_Count-1);//记录插入前最后元素的指针
  //先将待插入的元素全部插入链表后面
  for(int i=0;i< Size;i++)
  {
  Add(catList->GetAt(i));
  }
  CList* NewStartList=oldEndList->Next;//记录新插入元素的头指针
  CList* NewEndList=GetDataList(m_Count-1);//记录插入后最后元素的指针
  oldEndList->Next=NULL;//将新增的链表暂时与旧表断开
  if(Index==0)
  {
  NewEndList->Next=m_Head;
  m_Head=NewStartList;
  }
  else
  {
  CList* InertList=GetDataList(Index-1);
  NewEndList->Next=InertList->Next;
  InertList->Next=NewStartList;
  }
}
template<class T>
int CTempalteList<T>::SetAt(const unsigned int Index,T Data)
{
  assert(Index>=0&&Index<m_Count);
  if(Index<0||Index>=m_Count)return -1;
  CList* PreList=GetDataList(Index);//得到前一个元素的指针
  assert(PreList);
  PreList->Data=Data;
}
int main(void)
{
  CTempalteList<int> list;
  for(int i=0;i<5;i++)
  list.Add(i);
  list=list+list;
  list.SetAt(0,100);
  for(int i=0;i<list.GetSize();i++)
  cout<<list.GetAt(i)<<" ";
  return 0;
}

作者: w378567402   发布时间: 2011-12-04