分享

C 模版编程——单链表的实现

 Fredanf 2012-12-01

C++模版编程——单链表的实现

分类: C++基础 257人阅读 评论(0) 收藏 举报

代码的注释还是很清晰的,就不说废话了。

直接上代码:

  1. #pragma once  
  2. #include <assert.h>  
  3. #include <iostream>  
  4. using std::cout;  
  5. using std::endl;  
  6. //单链表模板类  
  7. template<class T>  
  8. class CList  
  9. {  
  10. public:  
  11.     //类方法接口  
  12.     enum{begin=0,end=-1};  
  13.     typedef struct _LIST  
  14.     {  
  15.         _LIST* pNext;//指向下一个元素  
  16.         T data;//数据域  
  17.     }LIST,*PLIST;  
  18.     explicit CList(const T s[],const int n);  
  19.     explicit CList();  
  20.     CList<T>& operator=(const CList<T>& l);//默认赋值操作符  
  21.     bool operator==(const CList<T>& l);//重载等于操作符  
  22.     friend bool operator==(const LIST& l1,const LIST& l2)  
  23.     {  
  24.         if((l1.data==l2.data))  
  25.             return true;  
  26.         return false;  
  27.     }  
  28.     virtual~ CList();  
  29.     //打印链表元素  
  30.     void Show()const;  
  31.     //获取元素数目  
  32.     void GetLength()const;  
  33.     //获取第index 个元素  
  34.     T GetAt(const int& index)const;  
  35.     T operator[](int index)const;  
  36.     //在第index个元素前插入元素t,插入末尾时约定index=-1  
  37.     void Insert(const T& t,const int& index=end);//默认情况下,在链表末尾插入  
  38.     void Insert(const T s[],const int count,const int& index=end);//在第index个元素前插入count个元素  
  39.     //删除索引为index 的元素  
  40.     void Delete(const int& index);  
  41.     //删除从index开始的n个元素,当n大于index开始的元素数目之和时,删除后面所有的  
  42.     void Delete(const int& index,const int& n);  
  43.     //删除索引为index1和index2之间的所有元素  
  44.     void DeleteBetween(const int& index1,const int& index2);//index1和index2之间大小不用限定  
  45.     //删除链表中所有元素  
  46.     void DeleteAll();  
  47.     //获取链表所有元素,存在数组中  
  48.     void GetData(T s[])const;  
  49.     //获取链表中最大元素  
  50.     T GetMaxData()const;  
  51.     //获取链表中最小元素  
  52.     T GetMinData()const;  
  53.     //对链表进行排序  
  54.     void SortList();  
  55.     //链表逆置  
  56.     void InverseList();  
  57.     //链表是否为空  
  58.     bool IsEmpty()const;  
  59.     //替换索引为index处的元素值  
  60.     void Replace(const T& t,const int& index);  
  61.     //用数组s[]中的count个元素替换index开始的count个节点的值  
  62.     void Replace(const T s[],const int& index,const int& count);  
  63.     //从pos开始查找,默认从第一个位置,按先后顺序查找元素值,返回索引值,没有找到返回-1,找到即停止  
  64.     int Find(const T& t,const int pos=begin);  
  65.     //从末尾开始查找,没找到返回-1  
  66.     int FindLastOf(const T& t,const int pos=end);  
  67.     //获取两个变量中大的一个  
  68.     inline int GetMax(const int& a,const int& b)const;  
  69.     //获取两个变量中小的那个  
  70.     inline int GetMin(const int& a,const int& b)const;  
  71. protected:  
  72.     void Release();//释放所有内存空间  
  73.     //释放index开始的所有内存空间  
  74.     void Release(const int& index);  
  75.     //释放index1到index2之间元素的内存空间  
  76.     void Release(const int& index1,const int& index2);  
  77.     //创建一个链表链接S[]内所有元素,返回首地址  
  78.     LIST* CreateList(const T s[],const int& count)const  
  79.     {  
  80.         assert(count>0);  
  81.         PLIST p1=new LIST;//第一个节点  
  82.         p1->data=s[0];  
  83.         PLIST temp=p1;  
  84.         for(int i=1;i<count-1;++i)  
  85.         {  
  86.             PLIST p=new LIST;  
  87.             p->data=s[i];  
  88.             temp->pNext=p;  
  89.             temp=p;  
  90.         }  
  91.         PLIST tail=new LIST;  
  92.         tail->data=s[count-1];  
  93.         temp->pNext=tail;  
  94.         tail->pNext=NULL;  
  95.         return p1;  
  96.     }  
  97.     //返回第index(从0开始索引)个元素的地址,默认值-1,返回头指针地址  
  98.     LIST* GetAddr(const int& index=-1)  
  99.     {  
  100.         assert(index>=-1&&index<m_iLength);  
  101.         if(index==-1)  
  102.             return pHeader;  
  103.         PLIST p=pHeader->pNext;  
  104.         for(int i=0;i<index;++i)  
  105.             p=p->pNext;  
  106.         return p;  
  107.     }  
  108.     //交换元素值  
  109.     inline void Swap(LIST* p1,LIST* p2)const;  
  110.     //快速排序算法  
  111.     int Partition(int low,int high);  
  112.     void QSort(int low,int high);  
  113.     void QuickSort();  
  114. private:  
  115.     //类属性  
  116.     PLIST pHeader;//指向数据域缓冲区首地址,data存放链表长度  
  117.     int m_iLength;//元素数目  
  118. };  
  119. //实现类方法  
  120. template<class T>  
  121. CList<T>::CList():pHeader(NULL),m_iLength(0)  
  122. {  
  123.     pHeader=new LIST;  
  124.     pHeader->pNext=NULL;  
  125.     pHeader->data=(T)0;  
  126. }  
  127. template<class T>  
  128. CList<T>::CList(const T s[], const int n):pHeader(NULL),m_iLength(n)  
  129. {  
  130.     assert(n>=0);  
  131.     pHeader=new LIST;  
  132.     pHeader->data=(T)0;  
  133.     pHeader->pNext=CreateList(s,n);  
  134. }  
  135. template<class T>  
  136. void CList<T>::Release()  
  137. {  
  138.     PLIST p=pHeader;  
  139.     while(p)  
  140.     {  
  141.         PLIST temp=p->pNext;  
  142.         delete p;  
  143.         p=temp;  
  144.     }  
  145.     pHeader=NULL;  
  146.     m_iLength=0;  
  147. }  
  148. template<class T>  
  149. CList<T>::~CList()  
  150. {  
  151.     Release();  
  152. }  
  153. template<class T>  
  154. void CList<T>::Show()const  
  155. {  
  156.     PLIST p=pHeader->pNext;  
  157.     for(int i=0;i<m_iLength-1;++i)  
  158.     {  
  159.         cout<<p->data<<"--->";  
  160.         p=p->pNext;  
  161.     }  
  162.     cout<<p->data<<endl;  
  163.     cout<<endl;  
  164. }  
  165. template<class T>  
  166. void CList<T>::GetLength() const  
  167. {  
  168.     return m_iLength;  
  169. }  
  170. template<class T>  
  171. T CList<T>::GetAt(const int& index) const  
  172. {  
  173.     assert(index>=0&&index<m_iLength);  
  174.     PLIST p=pHeader->pNext;  
  175.     for(int i=0;i<index;++i)  
  176.         p=p->pNext;  
  177.     return p->data;  
  178. }  
  179. template<class T>  
  180. T CList<T>::operator [](int index) const  
  181. {  
  182.     return GetAt(index);  
  183. }  
  184. template<class T>  
  185. CList<T>& CList<T>::operator =(const CList<T> &l)  
  186. {  
  187.     if(*this==l)  
  188.         return *this;  
  189.     Release();  
  190.     pHeader=new LIST;  
  191.     pHeader->data=(T)0;  
  192.     m_iLength=l.m_iLength;  
  193.     PLIST lp=pHeader;  
  194.     for(int i=0;i<m_iLength-1;++i)  
  195.     {  
  196.         PLIST p=new LIST;  
  197.         p->data=l[i];  
  198.         lp->pNext=p;  
  199.         lp=p;  
  200.     }  
  201.     PLIST tail=new LIST;  
  202.     tail->data=l[m_iLength-1];  
  203.     tail->pNext=NULL;  
  204.     lp->pNext=tail;  
  205.     return *this;  
  206. }  
  207. template<class T>  
  208. bool CList<T>::operator ==(const CList<T> &l)  
  209. {  
  210.     if(pHeader==l.pHeader)  
  211.         return true;  
  212.     return false;  
  213. }  
  214. template<class T>  
  215. void CList<T>::Insert(const T &t, const int& index = -1)  
  216. {  
  217.     assert(index>=-1&&index<m_iLength);//确保插入位置有效  
  218.     LIST* p=new LIST;  
  219.     p->data=t;  
  220.     if(index==-1)// 末尾插入  
  221.     {  
  222.         GetAddr(m_iLength-1)->pNext=p;  
  223.         p->pNext=NULL;  
  224.     }  
  225.     else  
  226.     {  
  227.         PLIST pl=NULL;  
  228.         if(index==0)  
  229.             pl=GetAddr();  
  230.         else  
  231.             pl=GetAddr(index-1);  
  232.         p->pNext=pl->pNext;  
  233.         pl->pNext=p;  
  234.     }  
  235.     m_iLength++;  
  236. }  
  237. template<class T>  
  238. void CList<T>::Insert(const T s[], const int count, const int& index = -1)  
  239. {  
  240.     assert(count>1);  
  241.     assert(index>=-1&&index<m_iLength);  
  242.     PLIST p=CreateList(s,count);  
  243.     if(index==-1)//末尾插入  
  244.         GetAddr(m_iLength-1)->pNext=p;  
  245.     else  
  246.     {  
  247.         PLIST p1=NULL;  
  248.         if(index==0)//头结点后插入  
  249.             p1=GetAddr();  
  250.         else  
  251.             p1=GetAddr(index-1);  
  252.         PLIST tail=p->pNext;  
  253.         while(true)//循环获取插入短链的尾指针  
  254.         {  
  255.             if(tail->pNext==NULL)  
  256.                 break;  
  257.             tail=tail->pNext;  
  258.         }  
  259.         tail->pNext=p1->pNext;  
  260.         p1->pNext=p;  
  261.     }  
  262.     m_iLength+=count;  
  263. }  
  264. template<class T>  
  265. void CList<T>::Delete(const int& index)  
  266. {  
  267.     assert(index>=0&&index<m_iLength);  
  268.     PLIST p=NULL;  
  269.     if(index==0)//删除第一个节点  
  270.     {  
  271.         p=pHeader->pNext;  
  272.         pHeader->pNext=p->pNext;  
  273.         delete p;  
  274.         p=NULL;  
  275.     }  
  276.     else if(index==m_iLength-1)//删除最后一个节点  
  277.     {  
  278.         p=GetAddr(m_iLength-2);  
  279.         PLIST temp=p->pNext;  
  280.         p->pNext=NULL;  
  281.         delete temp;  
  282.         temp=NULL;  
  283.     }  
  284.     else//其他情况  
  285.     {  
  286.         p=GetAddr(index-1);  
  287.         PLIST temp=p->pNext;  
  288.         p->pNext=temp->pNext;  
  289.         delete temp;  
  290.         temp=NULL;  
  291.     }  
  292.     m_iLength--;  
  293. }  
  294. template<class T>  
  295. void CList<T>::GetData(T s[]) const  
  296. {  
  297.     PLIST p=pHeader->pNext;  
  298.     int i=0;  
  299.     while(p)  
  300.     {  
  301.         s[i]=p->data;  
  302.         p=p->pNext;  
  303.         ++i;  
  304.     }  
  305. }  
  306. template<class T>  
  307. void CList<T>::DeleteAll()  
  308. {  
  309.     Release();  
  310.     pHeader=new LIST;  
  311.     pHeader->data=(T)0;  
  312.     pHeader->pNext=NULL;  
  313. }  
  314. template<class T>  
  315. void CList<T>::Delete(const int &index, const int &n)  
  316. {  
  317.     assert(index>=0&&index<m_iLength);  
  318.     assert(n>0);  
  319.     if(m_iLength-index<n)//删除index开始的所有元素  
  320.         Release(index);  
  321.     else//删除index开始的n个元素   
  322.         Release(index,n+index-1);  
  323. }  
  324. template<class T>  
  325. void CList<T>::DeleteBetween(const int& index1, const int& index2)  
  326. {  
  327.     assert(index1>=0&&index1<m_iLength);  
  328.     assert(index2>=0&&index2<m_iLength);  
  329.     Release(index1,index2);  
  330. }  
  331. template<class T>  
  332. void CList<T>::Release(const int &index)  
  333. {  
  334.     PLIST p=GetAddr(index-1);  
  335.     PLIST temp=p->pNext;//保存下一个节点  
  336.     p->pNext=NULL;  
  337.     while(temp)  
  338.     {  
  339.         PLIST lp=temp->pNext;  
  340.         delete temp;  
  341.         temp=lp;  
  342.     }  
  343.     m_iLength=index;  
  344. }  
  345. template<class T>  
  346. void CList<T>::Release(const int &index1, const int &index2)  
  347. {  
  348.     if(index1==index2)//不释放  
  349.         return;  
  350.     int max=GetMax(index1,index2);  
  351.     int min=GetMin(index1,index2);  
  352.     if(max==m_iLength-1)  
  353.     {  
  354.         Release(min);  
  355.         return;  
  356.     }  
  357.     PLIST p1=GetAddr(min-1);  
  358.     PLIST p2=p1->pNext;//保存需要删除内存首地址  
  359.     PLIST p3=GetAddr(max+1);  
  360.     p1->pNext=p3;//连接  
  361.     while(p2!=p3)  
  362.     {  
  363.         PLIST temp=p2->pNext;//保存下一个节点的地址  
  364.         delete p2;  
  365.         p2=temp;  
  366.     }  
  367.     m_iLength-=(max-min+1);  
  368. }  
  369. template <class T>  
  370. T CList<T>::GetMaxData() const  
  371. {  
  372.     assert(m_iLength>0);  
  373.     T max=GetAt(0);  
  374.     for(int i=1;i<m_iLength;++i)  
  375.     {  
  376.         T temp=GetAt(i);  
  377.         if(temp>max)  
  378.             max=temp;  
  379.     }  
  380.     return max;  
  381. }  
  382. template <class T>  
  383. T CList<T>::GetMinData() const  
  384. {  
  385.     assert(m_iLength>0);  
  386.     T min=GetAt(0);  
  387.     for(int i=1;i<m_iLength;++i)  
  388.     {  
  389.         T temp=GetAt(i);  
  390.         if(temp<min)  
  391.             min=temp;  
  392.     }  
  393.     return min;  
  394. }  
  395. template<class T>  
  396. void CList<T>::SortList()  
  397. {  
  398.     if(m_iLength<2)  
  399.         return;  
  400.     QuickSort();  
  401. }  
  402. template<class T>  
  403. inline void CList<T>::Swap(LIST* p1,LIST* p2)const  
  404. {  
  405.     T temp=p1->data;  
  406.     p1->data=p2->data;  
  407.     p2->data=temp;  
  408. }  
  409. template<class T>  
  410. void CList<T>::InverseList()  
  411. {  
  412.     if(m_iLength<2)  
  413.         return;  
  414.     int low=0,high=m_iLength-1;  
  415.     while(low<high)  
  416.     {  
  417.         Swap(GetAddr(low),GetAddr(high));  
  418.         low++;  
  419.         high--;  
  420.     }  
  421. }  
  422. template<class T>  
  423. int CList<T>::Partition(int low, int high)  
  424. {  
  425.     T key=GetAddr(low)->data;  
  426.     while(low<high)  
  427.     {  
  428.         while(low<high&&GetAddr(high)->data>=key)  
  429.             --high;  
  430.         GetAddr(low)->data=GetAddr(high)->data;  
  431.         while(low<high&&GetAddr(low)->data<=key)  
  432.             ++low;  
  433.         GetAddr(high)->data=GetAddr(low)->data;  
  434.     }  
  435.     GetAddr(low)->data=key;  
  436.     return low;  
  437. }  
  438. template<class T>  
  439. void CList<T>::QSort(int low, int high)  
  440. {  
  441.     if(low<high)  
  442.     {  
  443.         int ret=Partition(low,high);  
  444.         QSort(low,ret-1);  
  445.         QSort(ret+1,high);  
  446.     }  
  447. }  
  448. template<class T>  
  449. void CList<T>::QuickSort()  
  450. {  
  451.     QSort(0,m_iLength-1);  
  452. }  
  453. template<class T>  
  454. bool CList<T>::IsEmpty() const  
  455. {  
  456.     if(m_iLength)  
  457.         return false;  
  458.     return true;  
  459. }  
  460. template<class T>  
  461. void CList<T>::Replace(const T &t, const int &index)  
  462. {  
  463.     assert(index>=0&&index<m_iLength);  
  464.     GetAddr(index)->data=t;  
  465. }  
  466. template<class T>  
  467. void CList<T>::Replace(const T s[], const int &index, const int &count)  
  468. {  
  469.     assert(index>=0&&index<m_iLength);  
  470.     assert(count>=0);  
  471.     if(count==0)  
  472.         return;  
  473.     if(m_iLength-index>count)//替换count个元素  
  474.     {  
  475.         for(int i=0;i<count;++i)  
  476.             GetAddr(index+i)->data=s[i];  
  477.     }  
  478.     else//替换m_iLength-index个  
  479.     {  
  480.         for(int i=0;i<m_iLength-index;++i)  
  481.             GetAddr(index+i)->data=s[i];  
  482.     }  
  483. }  
  484. template<class T>  
  485. inline int CList<T>::GetMax(const int& a,const int& b)const  
  486. {  
  487.     if(a>b)  
  488.         return a;  
  489.     return b;  
  490. }  
  491. template<class T>  
  492. inline int CList<T>::GetMin(const int& a,const int& b)const  
  493. {  
  494.     if(a<b)  
  495.         return a;  
  496.     return b;  
  497. }  
  498. template<class T>  
  499. int CList<T>::Find(const T &t,const int pos)  
  500. {  
  501.     assert(pos>=0&&pos<m_iLength);  
  502.     int index=pos;  
  503.     PLIST p=GetAddr(pos);  
  504.     while(true)  
  505.     {  
  506.         if(p->data==t)  
  507.             return index;  
  508.         if(p->pNext==NULL)  
  509.             return -1;  
  510.         p=p->pNext;  
  511.         ++index;  
  512.     }  
  513. }  
  514. template<class T>  
  515. int CList<T>::FindLastOf(const T &t,const int pos)  
  516. {  
  517.     assert(pos>=-1&&pos<m_iLength);  
  518.     PLIST p=NULL;  
  519.     int index=pos;  
  520.     if(pos==end)  
  521.     {  
  522.         p=GetAddr(m_iLength-1);  
  523.         index=m_iLength-1;  
  524.     }  
  525.     else  
  526.         p=GetAddr(pos);  
  527.     while(true)  
  528.     {  
  529.         if(p->data==t)  
  530.             return index;  
  531.         if(index==0)  
  532.             return -1;  
  533.         --index;  
  534.         p=GetAddr(index);  
  535.     }  
  536. }  

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多