/* 單鏈表的聲明與實現(C++基於模板類) --模式參考了羅聰(資料結構與演算法分析學習筆記)
*
* 改進:多了一個表頭(啞結點),Sort(), Reverse(), Splice, Display(), ShowReverse()
*
* 日期:2009-2-9
*
* 作者:Virgil(hangyu_628@hotmail.com)
*
* Blog: http://blog.csdn.net/hangyu628/
*
* 若有bug的話,歡迎指出...
*
*/
#ifndef __SINGLE_LIST_H
#define __SINGLE_LIST_H
#include <iostream>
using namespace std;
//結點類
template <typename T>
class CNode
{
public:
T data;
CNode<T> *next;
CNode(): data(T()),next(NULL){}
CNode(const T &initData):data(initData),next(NULL){}
CNode(const T &initData, CNode<T> *pNext):data(initData),next(pNext){}
};
//單鏈表類
template <typename T>
class CSingleList
{
protected:
int m_nCount;
CNode<T> *m_pHeadNode;
public:
CSingleList();
CSingleList(const T &initData);
~CSingleList();
public:
int IsEmpty();
CNode<T>* GetHead();
int GetCount() const;
int AddFirst(const T data); //添加前面第一個元素
int AddTail(const T data);
int InsertBefore(const size_t pos, const T data);
int InsertAfter(const size_t pos, const T data);
void RemoveAt(const size_t pos);
void RemoveFirst();
void RemoveTail();
void RemoveAll();
T GetTail() const;
T GetFirst() const;
T GetAt(const size_t pos) const;
void SetAt(const size_t pos, T data);
size_t Find(const T data) const; //尋找資料的位置
void Sort() const; //排序
void Reverse() const; //逆序
void Display() const; //正常輸出
void ShowReverse(CNode<T> *m_pHeadNode) const; //用遞迴,逆序輸出
void Splice(CSingleList<T> &); //鏈表的接合
};
template <typename T>
inline int CSingleList<T>::GetCount() const
{
return m_nCount;
}
template <typename T>
inline CSingleList<T>::CSingleList():m_nCount(0)
{
if((m_pHeadNode=new CNode<T>)==NULL)
return;
m_pHeadNode->data=0;
m_pHeadNode->next=NULL;
}
template <typename T>
inline CSingleList<T>::CSingleList(const T &initData):m_nCount(0)
{
if((m_pHeadNode=new CNode<T>)==NULL)
return;
m_pHeadNode->data=0;
m_pHeadNode->next=NULL;
AddFirst(initData);
}
template <typename T>
inline CSingleList<T>::~CSingleList()
{
if (m_nCount!=0)
{
RemoveAll();
}
if (m_pHeadNode)
{
delete m_pHeadNode;
m_pHeadNode=NULL;
}
}
template <typename T>
inline int CSingleList<T>::IsEmpty()
{
return 0==m_nCount;
}
template <typename T>
inline CNode<T>* CSingleList<T>::GetHead()
{
return m_pHeadNode;
}
template <typename T>
inline int CSingleList<T>::AddFirst(const T data)
{
CNode<T> *pNewNode=new CNode<T>;
if (pNewNode==NULL)
return 0;
pNewNode->data=data;
pNewNode->next=m_pHeadNode->next;
m_pHeadNode->next=pNewNode;
++m_nCount;
return 1;
}
template <typename T>
inline int CSingleList<T>::AddTail(const T data)
{
CNode<T> *pTemp=m_pHeadNode->next;
if (pTemp==NULL)
{
AddFirst(data);
return 1;
}
for (int i=1;i!=m_nCount;++i)
{
pTemp=pTemp->next;
}
CNode<T> *pNewNode=new CNode<T>;
if (pNewNode==NULL)
return 0;
pNewNode->data=data;
pNewNode->next=NULL;
pTemp->next=pNewNode;
++m_nCount;
return 1;
}
template <typename T>
inline int CSingleList<T>::InsertBefore(const size_t pos, const T data)
{
if (pos<=0 || pos>m_nCount)
{
cout<<"You have inserted a error position."<<endl;
return 0;
}
CNode<T> *pNewNode=new CNode<T>;
if (pNewNode==NULL)
return 0;
pNewNode->data=data;
if (pos==1)//即插入到頭結點後...
{
pNewNode->next=m_pHeadNode->next;
m_pHeadNode->next=pNewNode;
}
else
{
CNode<T> *pTemp=m_pHeadNode->next;
//移到要插入的前一結點
for(int i=1;i!=pos-1;++i)
{
pTemp=pTemp->next;
}
pNewNode->next=pTemp->next;
pTemp->next=pNewNode;
}
++m_nCount;
return 1;
}
template <typename T>
inline int CSingleList<T>::InsertAfter(const size_t pos, const T data)
{
if (pos<=0 || pos>m_nCount)
{
cout<<"You have inserted a error position."<<endl;
return 0;
}
CNode<T> *pTemp=m_pHeadNode->next;
for(int i=1;i!=pos;++i)
{
pTemp=pTemp->next;
}
CNode<T> *pNewNode=new CNode<T>;
if (pNewNode==NULL)
return 0;
pNewNode->data=data;
pNewNode->next=pTemp->next;
pTemp->next=pNewNode;
++m_nCount;
return 1;
}
template <typename T>
inline void CSingleList<T>::RemoveAt(const size_t pos)
{
if (pos<=0 || pos>m_nCount)
{
cout<<"You have removed a error position."<<endl;
return;
}
CNode<T> *pTemp=m_pHeadNode,*qTemp=0;
//移到要刪的前一結點
for (int i=0;i!=pos-1;++i)
{
pTemp=pTemp->next;
}
qTemp=pTemp->next;
pTemp->next=qTemp->next;
delete qTemp;
qTemp=0;
--m_nCount;
}
template <typename T>
inline void CSingleList<T>::RemoveFirst()
{
if (m_nCount==0)
{
cout<<"There are no any datas."<<endl;
return;
}
CNode<T> *pTemp=m_pHeadNode->next;
m_pHeadNode->next=pTemp->next;
delete pTemp;
pTemp=NULL;
--m_nCount;
}
template <typename T>
inline void CSingleList<T>::RemoveTail()
{
if (m_nCount==0)
{
cout<<"There are no any datas."<<endl;
return;
}
CNode<T> *pTemp=m_pHeadNode;
while(pTemp->next!=NULL)
{
pTemp=pTemp->next;
}
delete pTemp;
pTemp=NULL;
--m_nCount;
}
//堆上建立的東西.先建立後刪除,能避免一些記憶體片段(如下用遞迴方法)
template <typename T>
inline void CSingleList<T>::RemoveAll()
{
if (m_nCount==0)
{
cout<<"There are no any datas."<<endl;
return;
}
CNode<T> *pTemp=m_pHeadNode->next;
if (pTemp->next!=NULL)
{
delete pTemp;
pTemp=pTemp->next;
}
pTemp=NULL;
m_nCount=0;
}
template <typename T>
inline T CSingleList<T>::GetFirst() const
{
if (m_nCount==0)
{
cout<<"There are no any datas."<<endl;
exit(EXIT_SUCCESS);
}
return m_pHeadNode->next->data;
}
template <typename T>
inline T CSingleList<T>::GetTail() const
{
if (m_nCount==0)
{
cout<<"There are no any datas."<<endl;
exit(0);
}
CNode<T> *pTemp=m_pHeadNode->next;
for (int i=1;i!=m_nCount;++i)
{
pTemp=pTemp->next;
}
return pTemp->data;
}
template <typename T>
inline T CSingleList<T>::GetAt(const size_t pos) const
{
if (pos<=0 || pos>m_nCount)
{
cout<<"You have inserted a error position."<<endl;
exit(EXIT_SUCCESS);
}
CNode<T> *pTemp=m_pHeadNode->next;
for (int i=1;i!=pos;++i)
{
pTemp=pTemp->next;
}
return pTemp->data;
}
template <typename T>
inline void CSingleList<T>::SetAt(const size_t pos, T data)
{
if (pos<=0 || pos>m_nCount)
{
cout<<"You have set a error position."<<endl;
exit(EXIT_SUCCESS);
}
CNode<T> *pTemp=m_pHeadNode->next;
for (int i=1;i!=pos;++i)
{
pTemp=pTemp->next;
}
pTemp->data=data;
}
template <typename T>
inline size_t CSingleList<T>::Find(const T data) const
{
CNode<T> *pTemp=m_pHeadNode;
for(int i=1;i!=m_nCount;++i)
{
pTemp=pTemp->next;
if (pTemp->data==data)
{
return i;
}
}
cout<<"The data is not exist."<<endl;
exit(EXIT_SUCCESS);
}
template <typename T>
inline void CSingleList<T>::Sort() const
{
CNode<T> *pTemp=m_pHeadNode->next,*qTemp;
if (pTemp==NULL)
return;
for (;pTemp!=NULL;pTemp=pTemp->next)
{
for (qTemp=pTemp->next;qTemp!=NULL;qTemp=qTemp->next)
{
if (pTemp->data>qTemp->data)
{
T tempData;
tempData=pTemp->data;
pTemp->data=qTemp->data;
qTemp->data=tempData;
}
}
}
}
template <typename T>
inline void CSingleList<T>::Reverse() const
{
CNode<T> *pTemp=m_pHeadNode->next,*qTemp=0;
while(pTemp!=NULL)
{
qTemp=pTemp;
pTemp=pTemp->next;
qTemp->next=m_pHeadNode->next;
m_pHeadNode->next=qTemp;
}
}
template <typename T>
inline void CSingleList<T>::Display() const
{
if (m_nCount==0)
{
cout<<"The link has no nodes."<<endl;
return;
}
CNode<T> *pTemp=m_pHeadNode->next;
for (int i=0;i!=m_nCount;++i)
{
cout<<pTemp->data<<" ";
pTemp=pTemp->next;
}
cout<<endl;
}
//用遞迴實現反向輸出...
template <typename T>
inline void CSingleList<T>::ShowReverse(CNode<T> *m_pHeadNode) const
{
if (m_nCount==0)
{
cout<<"The link has no nodes."<<endl;
return;
}
if (m_pHeadNode->next==NULL)
{
cout<<m_pHeadNode->data<<" ";
}
else
{
ShowReverse(m_pHeadNode->next);
if (m_pHeadNode->data!=0)
{
cout<<m_pHeadNode->data<<" ";
}
else
{
cout<<endl;
}
}
}
template <typename T>
inline void CSingleList<T>::Splice(CSingleList<T> &sList)
{
CNode<T> *pTemp=m_pHeadNode;
while(pTemp->next!=NULL)
{
pTemp=pTemp->next;
}
pTemp->next=sList.m_pHeadNode->next;
m_nCount+=sList.m_nCount;
}
#endif