单链表:
///
//
// FileName : slist(单链表).h
// Version : 0.10
// Author : Z X
// Date : 2014-4-29 19:58:38
// Comment :
//
///
#include <assert.h>
#include <iostream>
using namespace std;
#define ASSERT assert
template<typename T>
class CNode
{
public:
T m_data; //数据
CNode<T> *pnext; //下一个节点地址
CNode<T>(): m_data(T()) , pnext(NULL){}
CNode(const T &initdata) : m_data(initdata) , pnext(NULL){}
CNode(const T &initdata, const CNode<T> *p) : m_data(initdata) , pnext(p){}
};
template<typename T>
class CList
{
//构造与析构函数
public:
CList(){m_pNodeHead = NULL;}
CList(const T &initdata){AddHead(initdata);}
~CList();
//成员函数
public:
CList<T>* InitList();
int IsEmpty(); //判断是否为空
T& GetTail(); //得到一个引用,那么可以利用这个引用来改变链表中的值。
T GetTail() const; //得到一个对象,改变这个对象不能改变链表中的值。
T& GetHead(); //得到头
T GetHead() const;
T& GetAt(int pos); //得到pos处的值,假设1代表list中的第一个值
T GetAt(int pos) const;
void SetAt(int pos, const T &data); //将第pos处的值设为data
int GetCount() const; //得到总数
int Find(const T &data) const; //找到链表中值为data的结点位置,我们假设是第一个
int FindPrevious(const T &data); //找到值为data前面的结点位置
void Delete(const T &data); //删除值为data的结点
int InsertBefore(const int pos, const T data); //在pos前面插入值为data的结点
int InsertAfter(const int pos, const T data); //在pos后面插入值为data的结点
int AddHead(const T data); //添加头
int AddTail(const T data); //添加尾
void RemoveAt(const int pos); //删除pos处的结点
void RemoveHead(); //删除头
void RemoveTail(); //删除尾
void RemoveAll(); //删除所有元素
void PrintList(); //打印所有元素
void Test(); //测试函数
//成员变量
protected:
CNode<T> *m_pNodeHead;
};
//创建头结点。如果不想要头结点也可以,那么在List类中加入一个成员变量m_count,
//类似的写法见http://www.luocong.com/dsaanotes/index-Z-H-3.htm#node_sec_2.1
template<typename T>
CList<T>::~CList()
{
RemoveAll();
if(m_pNodeHead)
delete m_pNodeHead;
m_pNodeHead = NULL;
}
template<typename T>
CList<T> *CList<T>::InitList()
{
CNode<T> *pNewNode = new CNode<T>();
if(NULL == pNewNode)
return 0;
pNewNode->m_data = 0;
pNewNode->pnext = NULL;
m_pNodeHead = pNewNode;
return this;
}
template<typename T>
int CList<T>::AddHead(const T data)
{
ASSERT(m_pNodeHead);
CNode<T> *pNewNode = new CNode<T>();
if(NULL == pNewNode)
return 0;
pNewNode->m_data = data;
pNewNode->pnext = m_pNodeHead->pnext;
m_pNodeHead->pnext = pNewNode;
return 1;
}
template<typename T>
int CList<T>::AddTail(const T data)
{
ASSERT(m_pNodeHead);
CNode<T>*pTempNode = m_pNodeHead;
CNode<T> *pNewNode = new CNode<T>();
if(NULL == pNewNode)
return 0;
while(pTempNode->pnext != NULL)
{
pTempNode = pTempNode->pnext;
}
pNewNode->m_data = data;
pNewNode->pnext = pTempNode->pnext;
pTempNode->pnext = pNewNode;
return 1;
}
template<typename T>
int CList<T>::IsEmpty()
{
return m_pNodeHead == NULL;
}
template<typename T>
T& CList<T>::GetHead()
{
ASSERT(m_pNodeHead);
return m_pNodeHead->pnext->m_data; //用了两次查询地址,略烦。
}
template<typename T>
T CList<T>::GetHead() const
{
ASSERT(m_pNodeHead);
return m_pNodeHead->pnext->m_data; //用了两次查询地址
}
template<typename T>
T& CList<T>::GetTail()
{
ASSERT(m_pNodeHead);
CNode<T>*pTempNode = m_pNodeHead->pnext;
while(pTempNode->pnext != NULL)
pTempNode = pTempNode->pnext;
return pTempNode->m_data;
}
template<typename T>
T CList<T>::GetTail() const
{
ASSERT(m_pNodeHead);
CNode<T>*pTempNode = m_pNodeHead->pnext;
while(pTempNode->pnext != NULL)
pTempNode = pTempNode->pnext;
return pTempNode->m_data;
}
template<typename T>
T& CList<T>::GetAt(int pos)
{
ASSERT(m_pNodeHead);
int i = 1;
CNode<T>*pTempNode = m_pNodeHead->pnext;
while(i != pos)
{
pTempNode = pTempNode->pnext;
++i;
}
return pTempNode->m_data;
}
template<typename T>
T CList<T>::GetAt(int pos) const
{
ASSERT(m_pNodeHead);
int i = 1;
CNode<T>*pTempNode = m_pNodeHead->pnext;
while(i != pos)
{
pTempNode = pTempNode->pnext;
++i;
}
return pTempNode->m_data
}
template<typename T>
void CList<T>::SetAt(int pos, const T &data)
{
int i = 1;
ASSERT(m_pNodeHead);
CNode<T>*pTempNode = m_pNodeHead->pnext;
while(i != pos)
{
pTempNode = pTempNode->pnext;
++i;
}
pTempNode->m_data = data;
}
template<typename T>
int CList<T>::GetCount() const
{
ASSERT(m_pNodeHead);
int i = 0;
CNode<T>*pTempNode = m_pNodeHead->pnext;
while(pTempNode != NULL)
{
pTempNode = pTempNode->pnext;
++i;
}
return i;
}
template<typename T>
int CList<T>::Find(const T &data) const
{
ASSERT(m_pNodeHead);
int i = 1;
CNode<T>*pTempNode = m_pNodeHead->pnext;
while(pTempNode->m_data != data && pTempNode != NULL)
{
pTempNode = pTempNode->pnext;
++i;
}
return pTempNode != NULL ? i : -1;
}
template<typename T>
int CList<T>::FindPrevious(const T &data)
{
ASSERT(m_pNodeHead);
int i = 0;
CNode<T>*pTempNode = m_pNodeHead->pnext;
CNode<T>*pTempPrevious = m_pNodeHead;
while(pTempNode->m_data != data && pTempNode != NULL)
{
pTempPrevious = pTempNode;
pTempNode = pTempNode->pnext;
++i;
}
return pTempNode != NULL ? i : -1;
}
template<typename T>
void CList<T>::Delete(const T &data)
{
ASSERT(m_pNodeHead);
CNode<T>*pTempNode = m_pNodeHead->pnext;
CNode<T>*pTempPrevious = m_pNodeHead;
while(pTempNode && pTempNode->m_data != data)
{
pTempPrevious = pTempNode;
pTempNode = pTempNode->pnext;
}
if(pTempNode != NULL)
{
pTempPrevious->pnext = pTempNode->pnext;
delete pTempNode;
pTempNode = NULL;
}
}
template<typename T>
int CList<T>::InsertBefore(const int pos, const T data)
{
ASSERT(m_pNodeHead);
int i = 1;
CNode<T>*pTempNode = m_pNodeHead->pnext;
CNode<T>*pTempPrevious = m_pNodeHead;
while(pTempNode && i != pos)
{
pTempPrevious = pTempNode;
pTempNode = pTempNode->pnext;
++i;
}
CNode<T>*pInsertNode = new CNode<T>();
if(pInsertNode == NULL)
return -1;
pTempPrevious->pnext = pInsertNode;
pInsertNode->pnext = pTempNode;
pInsertNode->m_data = data;
return i;
}
template<typename T>
int CList<T>::InsertAfter(const int pos, const T data) //此处,如果pos超过总数,则插在最后一个结点处
{
ASSERT(m_pNodeHead);
int i = 0;
CNode<T>*pTempNode = m_pNodeHead;
while(pTempNode->pnext != NULL && i != pos)
{
pTempNode = pTempNode->pnext;
++i;
}
CNode<T>*pInsertNode = new CNode<T>();
if(pInsertNode == NULL)
return -1;
pInsertNode->pnext = pTempNode->pnext;
pTempNode->pnext = pInsertNode;
pInsertNode->m_data = data;
return i+1;
}
template<typename T>
void CList<T>::RemoveAt(const int pos)
{
ASSERT(m_pNodeHead);
ASSERT(pos);
int i = 1;
CNode<T>*pTempNode = m_pNodeHead->pnext;
CNode<T>*pTempPrevious = m_pNodeHead;
while(pTempNode && i != pos)
{
pTempPrevious = pTempNode;
pTempNode = pTempNode->pnext;
++i;
}
if(pTempNode != NULL)
{
pTempPrevious->pnext = pTempNode->pnext;
delete pTempNode;
pTempNode = NULL;
}
}
template<typename T>
void CList<T>::RemoveHead()
{
ASSERT(m_pNodeHead);
CNode<T>*pTempNode = m_pNodeHead->pnext;
if(pTempNode != NULL)
{
CNode<T>*pTempNextNode = pTempNode->pnext;
delete pTempNode;
pTempNode = NULL;
m_pNodeHead->pnext = pTempNextNode;
}
}
template<typename T>
void CList<T>::RemoveTail()
{
ASSERT(m_pNodeHead);
CNode<T>*pTempNode = m_pNodeHead->pnext;
CNode<T>*pPrevisNode = pTempNode;
if(pTempNode == NULL)
return;
while(pTempNode->pnext != NULL)
{
pPrevisNode = pTempNode;
pTempNode = pTempNode->pnext;
}
delete pTempNode;
pTempNode = NULL;
pPrevisNode->pnext = NULL;
}
template<typename T>
void CList<T>::RemoveAll() //!!!!!!!!!!!注意,此处是为了保证可以删除list中除去头结点外的其他元素。
{
CNode<T>*pTempNode = m_pNodeHead;
CNode<T>*pTempRemove = m_pNodeHead->pnext;
if(pTempRemove == NULL)
return;
while(pTempNode!= NULL)
{
pTempNode = pTempRemove->pnext;
delete pTempRemove;
pTempRemove = pTempNode;
}
m_pNodeHead->pnext = NULL;
}
template<typename T>
void CList<T>::PrintList()
{
int i,nCount;
nCount = GetCount();
// print out elements
for (i = 0; i < nCount; ++i)
cout << GetAt(i + 1);
cout <<endl;
}
template<typename T>
void CList<T>::Test()
{
InsertAfter(InsertAfter(AddHead(1), 2), 3);
PrintList();
InsertAfter(InsertAfter(GetCount(), 4), 5);
PrintList();
InsertAfter(GetCount(), 6);
PrintList();
AddTail(10);
PrintList();
InsertAfter(InsertBefore(GetCount(), 7), 8);
PrintList();
SetAt(GetCount(), 9);
PrintList();
RemoveHead();
PrintList();
RemoveTail();
PrintList();
cout << Find(3)<<endl;
cout << FindPrevious(3)<<endl;
Delete(3);
PrintList();
RemoveAt(3);
PrintList();
RemoveHead();
PrintList();
RemoveTail();
PrintList();
RemoveAll();
}
双向链表
#include <assert.h>
#include <iostream>
#define ASSERY assert
using namespace std;
template<typename Y>
class CDNode
{
public:
Y m_data; //数据
CDNode<Y> *pnext; //下一个节点地址
CDNode<Y> *ppre;
CDNode<Y>(): m_data(Y()) , pnext(NULL), ppre(NULL){}
CDNode(const Y &initdata) : m_data(initdata) , pnext(NULL), ppre(NULL){}
CDNode(const Y &initdata, const CDNode<Y> *p) : m_data(initdata) , pnext(p),ppre(NULL){}
};
template<typename Y>
class CDList
{
//构造与析构函数
public:
CDList(){m_pNodeHead = NULL;}
CDList(const Y &initdata){AddHead(initdata);}
~CDList();
//成员函数
public:
CDList<Y>* InitList();
int IsEmpty(); //判断是否为空
Y& GetTail(); //得到一个引用,那么可以利用这个引用来改变链表中的值。
Y GetTail() const; //得到一个对象,改变这个对象不能改变链表中的值。
Y& GetHead(); //得到头
Y GetHead() const;
Y& GetAt(int pos); //得到pos处的值,假设1代表list中的第一个值
Y GetAt(int pos) const;
void SetAt(int pos, const Y &data); //将第pos处的值设为data
int GetCount() const; //得到总数
int Find(const Y &data) const; //找到链表中值为data的结点位置,我们假设是第一个
int FindPrevious(const Y &data); //找到值为data前面的结点位置
void Delete(const Y &data); //删除值为data的结点
int InsertBefore(const int pos, const Y data); //在pos前面插入值为data的结点
int InsertAfter(const int pos, const Y data); //在pos后面插入值为data的结点
int AddHead(const Y data); //添加头
int AddTail(const Y data); //添加尾
void RemoveAt(const int pos); //删除pos处的结点
void RemoveHead(); //删除头
void RemoveTail(); //删除尾
void RemoveAll(); //删除所有元素
void PrintList(); //打印所有元素
void Test(); //测试函数
//成员变量
protected:
CDNode<Y> *m_pNodeHead;
};
template<typename Y>
CDList<Y>::~CDList()
{
RemoveAll();
if(m_pNodeHead)
delete m_pNodeHead;
m_pNodeHead = NULL;
}
template<typename Y>
CDList<Y> *CDList<Y>::InitList()
{
CDNode<Y> *pNewNode = new CDNode<Y>();
if(NULL == pNewNode)
return 0;
pNewNode->m_data = 0;
pNewNode->pnext = NULL;
pNewNode->ppre = NULL;
m_pNodeHead = pNewNode;
return this;
}
template<typename Y>
int CDList<Y>::AddHead(const Y data)
{
ASSERY(m_pNodeHead);
CDNode<Y> *pNewNode = new CDNode<Y>();
if(NULL == pNewNode)
return 0;
pNewNode->m_data = data;
pNewNode->pnext = m_pNodeHead->pnext;
pNewNode->ppre = m_pNodeHead;
m_pNodeHead->pnext = pNewNode;
return 1;
}
template<typename Y>
int CDList<Y>::AddTail(const Y data)
{
ASSERY(m_pNodeHead);
CDNode<Y>*pYempNode = m_pNodeHead;
CDNode<Y> *pNewNode = new CDNode<Y>();
if(NULL == pNewNode)
return 0;
while(pYempNode->pnext != NULL)
{
pYempNode = pYempNode->pnext;
}
pNewNode->m_data = data;
pNewNode->pnext = pYempNode->pnext;
pYempNode->pnext = pNewNode;
pNewNode->ppre = pYempNode;
return 1;
}
template<typename Y>
int CDList<Y>::IsEmpty()
{
return m_pNodeHead->next == NULL;
}
template<typename Y>
Y& CDList<Y>::GetHead()
{
ASSERY(m_pNodeHead);
return m_pNodeHead->pnext->m_data; //用了两次查询地址,略烦。
}
template<typename Y>
Y CDList<Y>::GetHead() const
{
ASSERY(m_pNodeHead);
return m_pNodeHead->pnext->m_data; //用了两次查询地址
}
template<typename Y>
Y& CDList<Y>::GetTail()
{
ASSERY(m_pNodeHead);
CDNode<Y>*pYempNode = m_pNodeHead->pnext;
while(pYempNode->pnext != NULL)
pYempNode = pYempNode->pnext;
return pYempNode->m_data;
}
template<typename Y>
Y CDList<Y>::GetTail() const
{
ASSERY(m_pNodeHead);
CDNode<Y>*pYempNode = m_pNodeHead->pnext;
while(pYempNode->pnext != NULL)
pYempNode = pYempNode->pnext;
return pYempNode->m_data;
}
template<typename Y>
Y& CDList<Y>::GetAt(int pos)
{
ASSERY(m_pNodeHead);
int i = 1;
CDNode<Y>*pYempNode = m_pNodeHead->pnext;
while(i != pos)
{
pYempNode = pYempNode->pnext;
++i;
}
return pYempNode->m_data;
}
template<typename Y>
Y CDList<Y>::GetAt(int pos) const
{
ASSERY(m_pNodeHead);
int i = 1;
CDNode<Y>*pYempNode = m_pNodeHead->pnext;
while(i != pos)
{
pYempNode = pYempNode->pnext;
++i;
}
return pYempNode->m_data
}
template<typename Y>
void CDList<Y>::SetAt(int pos, const Y &data)
{
int i = 1;
ASSERY(m_pNodeHead);
CDNode<Y>*pYempNode = m_pNodeHead->pnext;
while(i != pos)
{
pYempNode = pYempNode->pnext;
++i;
}
pYempNode->m_data = data;
}
template<typename Y>
int CDList<Y>::GetCount() const
{
ASSERY(m_pNodeHead);
int i = 0;
CDNode<Y>*pYempNode = m_pNodeHead->pnext;
while(pYempNode != NULL)
{
pYempNode = pYempNode->pnext;
++i;
}
return i;
}
template<typename Y>
int CDList<Y>::Find(const Y &data) const
{
ASSERY(m_pNodeHead);
int i = 1;
CDNode<Y>*pYempNode = m_pNodeHead->pnext;
while(pYempNode->m_data != data && pYempNode != NULL)
{
pYempNode = pYempNode->pnext;
++i;
}
return pYempNode != NULL ? i : -1;
}
template<typename Y>
int CDList<Y>::FindPrevious(const Y &data)
{
ASSERY(m_pNodeHead);
int i = 0;
CDNode<Y>*pYempNode = m_pNodeHead->pnext;
while(pYempNode->m_data != data && pYempNode != NULL)
{
pYempNode = pYempNode->pnext;
++i;
}
return pYempNode != NULL ? i : -1;
}
template<typename Y>
void CDList<Y>::Delete(const Y &data)
{
ASSERY(m_pNodeHead);
CDNode<Y>*pYempNode = m_pNodeHead->pnext;
while(pYempNode && pYempNode->m_data != data)
{
pYempNode = pYempNode->pnext;
}
if(pYempNode != NULL)
{
pYempNode->ppre->pnext = pYempNode->pnext;
pYempNode->pnext->ppre = pYempNode->ppre;
delete pYempNode;
pYempNode = NULL;
}
}
template<typename Y>
int CDList<Y>::InsertBefore(const int pos, const Y data)
{
ASSERY(m_pNodeHead);
int i = 1;
CDNode<Y>*pYempNode = m_pNodeHead->pnext;
while(pYempNode && i != pos)
{
pYempNode = pYempNode->pnext;
++i;
}
CDNode<Y>*pInsertNode = new CDNode<Y>();
if(pInsertNode == NULL)
return -1;
pYempNode->ppre->pnext = pInsertNode;
pInsertNode->ppre = pYempNode->ppre;
pInsertNode->pnext = pYempNode;
pInsertNode->m_data = data;
return i;
}
template<typename Y>
int CDList<Y>::InsertAfter(const int pos, const Y data) //此处,如果pos超过总数,则插在最后一个结点处
{
ASSERY(m_pNodeHead);
int i = 0;
CDNode<Y>*pYempNode = m_pNodeHead;
while(pYempNode->pnext != NULL && i != pos)
{
pYempNode = pYempNode->pnext;
++i;
}
CDNode<Y>*pInsertNode = new CDNode<Y>();
if(pInsertNode == NULL)
return -1;
pInsertNode->pnext = pYempNode->pnext;
if(pYempNode->pnext!=NULL)
pYempNode->pnext->ppre = pInsertNode;
pYempNode->pnext = pInsertNode;
pInsertNode->ppre = pYempNode;
pInsertNode->m_data = data;
return i+1;
}
template<typename Y>
void CDList<Y>::RemoveAt(const int pos)
{
ASSERY(m_pNodeHead);
ASSERY(pos);
int i = 1;
CDNode<Y>*pYempNode = m_pNodeHead->pnext;
while(pYempNode && i != pos)
{
pYempNode = pYempNode->pnext;
++i;
}
if(pYempNode != NULL)
{
pYempNode->ppre->pnext = pYempNode->pnext;
if(pYempNode->pnext != NULL)
pYempNode->pnext->ppre = pYempNode->ppre;
delete pYempNode;
pYempNode = NULL;
}
}
template<typename Y>
void CDList<Y>::RemoveHead()
{
ASSERY(m_pNodeHead);
CDNode<Y>*pYempNode = m_pNodeHead->pnext;
if(pYempNode != NULL)
{
m_pNodeHead->pnext = pYempNode->pnext;
if(pYempNode->pnext != NULL)
pYempNode->pnext->ppre = m_pNodeHead;
delete pYempNode;
pYempNode = NULL;
}
}
template<typename Y>
void CDList<Y>::RemoveTail()
{
ASSERY(m_pNodeHead);
CDNode<Y>*pYempNode = m_pNodeHead->pnext;
if(pYempNode == NULL)
return;
while(pYempNode->pnext != NULL)
{
pYempNode = pYempNode->pnext;
}
pYempNode->ppre->pnext = NULL;
delete pYempNode;
pYempNode = NULL;
}
template<typename Y>
void CDList<Y>::RemoveAll() //!!!!!!!!!!!注意,此处是为了保证可以删除list中除去头结点外的其他元素。
{
CDNode<Y>*pYempNode = m_pNodeHead;
CDNode<Y>*pYempRemove = m_pNodeHead->pnext;
if(pYempRemove == NULL)
return;
while(pYempNode!= NULL)
{
pYempNode = pYempRemove->pnext;
delete pYempRemove;
pYempRemove = pYempNode;
}
m_pNodeHead->pnext = NULL;
}
template<typename Y>
void CDList<Y>::PrintList()
{
int i,nCount;
nCount = GetCount();
// print out elements
for (i = 0; i < nCount; ++i)
cout << GetAt(i + 1);
cout <<endl;
}
template<typename Y>
void CDList<Y>::Test()
{
InsertAfter(InsertAfter(AddHead(1), 2), 3);
PrintList();
InsertAfter(InsertAfter(GetCount(), 4), 5);
PrintList();
InsertAfter(GetCount(), 6);
PrintList();
AddTail(10);
PrintList();
InsertAfter(InsertBefore(GetCount(), 7), 8);
PrintList();
SetAt(GetCount(), 9);
PrintList();
RemoveHead();
PrintList();
RemoveTail();
PrintList();
cout << Find(3)<<endl;
cout << FindPrevious(3)<<endl;
Delete(3);
PrintList();
RemoveAt(3);
PrintList();
RemoveHead();
PrintList();
RemoveTail();
PrintList();
RemoveAll();
}
循环列表就是将尾链表的pnext指向head,此处就不再贴出代码了