一、循环链表的简介
循环链表在单链表的基础上使最后的一个节点的指针指向开始的节点形成一个循环的数据结构体,没有空指针的出现。
循环链表在操作上和单链表差不多,单需要注意的是最后一个节点的指针用于时指向头结点的地址的。
二、循环链表的c++实现
AL_Node.h文件代码
#ifndef AL_NODE_INCLUDE
#define AL_NODE_INCLUDE
#include <windows.h>
template<typename T> class AL_ListCtrcularSingle;
template<typename T>
class AL_Node
{
//声明一个朋友类,使这个朋友类可以访问这个类的私有元素
friend class AL_ListCtrcularSingle<T>;
public :
~AL_Node();
private :
AL_Node();
AL_Node(const T &tTemplate);
AL_Node(const AL_Node<T>& cAL_Node);
T m_data;//存储数据
AL_Node *m_pPre;//记录链表的头结点地址
AL_Node *m_pNext; //指向下一个节点地址
};
template<typename T>
AL_Node<T>::AL_Node():m_pPre(NULL),m_pNext(NULL)
{
}
template<typename T>
AL_Node<T>::AL_Node(const T &tTemplate):m_pPre(NULL),m_pNext(NULL),m_data(tTemplate)
{
}
template<typename T>
AL_Node<T>::~AL_Node()
{
m_pPre=NULL;
m_pNext=NULL;
}
#endif // AL_NODE
AL_ListCtrcularSingle.h文件
#ifndef AL_LISTCIRCULARSINGLE_INCLUDE
#define AL_LISTCIRCULARSINGLE_INCLUDE
#include <windows.h>
#include "AL_Node.h"
template<typename T>
class AL_ListCtrcularSingle
{
public:
static const DWORD LISTDOUBLE_POSITION_INVALID = 0xffffffff;
AL_ListCtrcularSingle();
~AL_ListCtrcularSingle();
DWORD Length() const;
DWORD Find(const T &tTemplate)const;
bool IsElement(const T & tTemplate)const;
bool Insert(DWORD dwIndex, const T & tTemplate);
bool InsertBegin(const T &tTemplate);
bool InsertEnd(const T &tTemplate);
bool Remove(const T &tTemplate);
bool IsEmpty()const;
bool Get(T & tTypeOut, DWORD dwIndex)const;
bool Set(const DWORD &tTemplate, DWORD dwIndex, T &tTypeOut);
void Clear();
private:
AL_Node<T> * GetNodeByIndex(DWORD dwIndex) const;
AL_Node<T> * m_Header;
DWORD m_dwSize;
};
template<typename T>
inline AL_ListCtrcularSingle<T>::AL_ListCtrcularSingle() : m_Header(NULL),m_dwSize(0x00)
{
m_Header = new AL_Node<T>();
//循环指向自己
m_Header->m_pNext = m_Header;
}
template<typename T>
inline AL_ListCtrcularSingle<T>::~AL_ListCtrcularSingle()
{
Clear();
if (m_Header!=NULL)
{
delete m_Header;
m_Header = NULL;
}
}
template<typename T>
inline DWORD AL_ListCtrcularSingle<T>::Length() const
{
return m_dwSize;
}
template<typename T>
inline DWORD AL_ListCtrcularSingle<T>::Find(const T & tTemplate) const
{
if (IsEmpty()==true)
{
return LISTDOUBLE_POSITION_INVALID;
}
AL_Node<T> *pMove = NULL;
DWORD dwCount = 1;
pMove = m_Header->m_pNext;
while (pMove->m_pNext != NULL)
{
if (pMove->m_data==tTemplate)
{
//链表节点从零开始索引
return dwCount - 1;
}
dwCount++;
pMove = pMove->m_pNext;
}
if (pMove->m_data==tTemplate)
{
return dwCount - 1;
}
return LISTDOUBLE_POSITION_INVALID;
}
template<typename T>
inline bool AL_ListCtrcularSingle<T>::IsElement(const T & tTemplate) const
{
if (Find()==LISTDOUBLE_POSITION_INVALID)
{
return false;
}
return true;
}
template<typename T>
inline bool AL_ListCtrcularSingle<T>::Insert(DWORD dwIndex, const T & tTemplate)
{
if (dwIndex>Length())
{
return false;
}
AL_Node<T> *pInsert = new AL_Node<T>();
pInsert->m_data = tTemplate;
AL_Node<T> * pPer = NULL;
if (dwIndex==0x00)
{
pPer = m_Header;
}
else
{
pPer = GetNodeByIndex(dwIndex - 1);
}
if (pPer==NULL)
{
return false;
}
if (dwIndex==Length())
{
pPer->m_pNext = pInsert;
//循环指向头结点
pInsert->m_pNext = m_Header;
}
else
{
AL_Node<T> *pIndexNode = pPer->m_pNext;
if (pIndexNode==NULL)
{
return false;
}
pInsert->m_pNext = pIndexNode;
pPer->m_pNext = pInsert;
}
m_dwSize++;
return true;
}
template<typename T>
inline bool AL_ListCtrcularSingle<T>::InsertBegin(const T & tTemplate)
{
return Insert(0x00, tTemplate);
}
template<typename T>
inline bool AL_ListCtrcularSingle<T>::InsertEnd(const T & tTemplate)
{
return Find(Length(), tTemplate);
}
template<typename T>
inline bool AL_ListCtrcularSingle<T>::Remove(const T & tTemplate)
{
if (IsEmpty()==true)
{
return false;
}
DWORD dwPosition = Find(tTemplate);
if (dwPosition==LISTDOUBLE_POSITION_INVALID)
{
return false;
}
AL_Node<T> * pDelete = GetNodeByIndex(dwPosition);
if (pDelete==NULL)
{
return false;
}
AL_Node<T> *pPer = NULL;
//若要删除的节点时头节点
if (dwPosition == 0x00)
{
pPer = m_Header;
}
else
{
pPer = GetNodeByIndex(dwPosition - 1);
}
if (pPer==NULL)
{
return false;
}
//指向要删除的节点的下一个节点
pPer->m_pNext = pDelete->m_pNext;
m_dwSize--;
return true;
}
template<typename T>
inline bool AL_ListCtrcularSingle<T>::IsEmpty() const
{
//判断是否指向了头节点
return (m_Header->m_pNext==m_Header)?true:false;
}
template<typename T>
inline bool AL_ListCtrcularSingle<T>::Get(T & tTypeOut, DWORD dwIndex) const
{
if (IsEmpty()==true)
{
return false;
}
if (dwIndex>Length()-1)
{
return false;
}
AL_Node<T> * dwGet = GetNodeByIndex(dwIndex);
if (dwGet==NULL)
{
return false;
}
tTypeOut = dwGet->m_data;
return true;
}
template<typename T>
inline bool AL_ListCtrcularSingle<T>::Set(const DWORD & tTemplate, DWORD dwIndex, T & tTypeOut)
{
if (IsEmpty()==true)
{
return false;
}
//保证在索引值范围内
if (dwIndex>Length()-1)
{
return false;
}
AL_Node<T> *pSet = GetNodeByIndex(dwIndex);
if (pSet==NULL)
{
return false;
}
tTypeOut = pSet->m_data;
pSet->m_data = tTemplate;
return true;
}
template<typename T>
inline void AL_ListCtrcularSingle<T>::Clear()
{
if (IsEmpty()==true)
{
return;
}
AL_Node<T> * pDelete = NULL;
//判断是否指向头节点
while (m_Header->m_pNext!=m_Header)
{
pDelete = m_Header->m_pNext;
m_Header->m_pNext = pDelete->m_pNext;
delete pDelete;
pDelete = NULL;
}
m_dwSize = 0x00;
}
template<typename T>
inline AL_Node<T>* AL_ListCtrcularSingle<T>::GetNodeByIndex(DWORD dwIndex) const
{
if (dwIndex>Length()-1)
{
return false;
}
DWORD dwCount = 1;
AL_Node<T> *pMove = m_Header->m_pNext;
while (pMove->m_pNext!=m_Header)
{
if (dwIndex==dwCount-1)
{
return pMove;
}
pMove = pMove->m_pNext;
dwCount++;
}
//最后一个节点
return pMove;
}
#endif
测试代码
void ListCircularSingleTest()
{
AL_ListCtrcularSingle<DWORD> cListCtrcularSingle;
bool bEmpty = cListCtrcularSingle.IsEmpty();
std::cout << bEmpty << std::endl;
//节点的插入
int array[15] = { 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 };
for (int i = 0; i < 15; i++)
cListCtrcularSingle.Insert(cListCtrcularSingle.Length(), array[i]);
bEmpty = cListCtrcularSingle.IsEmpty();
DWORD dwLength = cListCtrcularSingle.Length();
std::cout << bEmpty <<" "<<dwLength<<std::endl;
//节点的删除
bEmpty = cListCtrcularSingle.Remove(cListCtrcularSingle.Length());
dwLength = cListCtrcularSingle.Length();
std::cout << bEmpty << " " << dwLength << std::endl;
//修改获取节点
DWORD baa;
DWORD saa;
bEmpty = cListCtrcularSingle.Set(8, 5, baa);
bool saaa = cListCtrcularSingle.Get(saa, 5);
std::cout << bEmpty << " " << saaa << " " << baa << " " << saa << std::endl;
}
int main(int argc, char *argv[])
{
ListCircularSingleTest();
getchar();
return 0;
}
运行结果 :