双向循环链表的结构是在双向链表的基础上使头节点的前驱指针指向末尾的节点,而使末尾的节点的一个指针指向开始节点,形成一个循环结构。
双向循环链表在进行节点的删除的时候的操作:
AL_Node.h文件
#ifndef AL_NODE_INCLUDE
#define AL_NODE_INCLUDE
#include
template<typename T> class AL_ListCircuarDouble;
template<typename T>
class AL_Node
{
//声明一个朋友类,使这个朋友类可以访问这个类的私有元素
friend class AL_ListCircuarDouble;
public:
~AL_Node();
private:
AL_Node();
AL_Node(const T &tTemplate);
AL_Node(const AL_Node& cAL_Node);
T m_data;//存储数据
AL_Node *m_pPre;//记录链表的头结点地址
AL_Node *m_pNext; //指向下一个节点地址
};
template<typename T>
AL_Node::AL_Node() :m_pPre(NULL), m_pNext(NULL)
{
}
template<typename T>
AL_Node::AL_Node(const T &tTemplate) :m_pPre(NULL), m_pNext(NULL), m_data(tTemplate)
{
}
template<typename T>
AL_Node::~AL_Node()
{
m_pPre = NULL;
m_pNext = NULL;
}
#endif // AL_NODE
AL_ListCircularDouble.h文件
#ifndef AL_LISTCIRCULARDOUBLE_INCLUDE
#define AL_LISTCIRCULARSINGLE_INCLUDE
#include
#include "AL_Node.h"
template<typename T>
class AL_ListCircuarDouble
{
public:
static const DWORD LISTDOUBLE_POSITION_INVALID = 0xffffffff;
AL_ListCircuarDouble();
~AL_ListCircuarDouble();
//获取当前链表中节点的个数
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(T& tTypeOut, DWORD dwIndex, const T& tTemplate);
//删除整个表中的节点
void Clear();
private:
//根据索引寻找链表中的节点
AL_Node* GetNodeByIndex(DWORD dwIndex) const;
DWORD m_dwSize;//记录当前链表中节点的个数
AL_Node* m_pHeader;//节点数据结构对象。
};
#endif
template<typename T>
inline AL_ListCircuarDouble::AL_ListCircuarDouble():m_pHeader(NULL),m_dwSize(0x00)
{
m_pHeader = new AL_Node();
m_pHeader->m_pPre = m_pHeader;
m_pHeader->m_pNext = m_pHeader;
}
template<typename T>
inline AL_ListCircuarDouble::~AL_ListCircuarDouble()
{
Clear();
if (m_pHeader!=NULL)
{
delete m_pHeader;
m_pHeader = NULL;
}
}
template<typename T>
inline DWORD AL_ListCircuarDouble::Length() const
{
return m_dwSize;
}
template<typename T>
inline DWORD AL_ListCircuarDouble::Find(const T & tTemplate) const
{
if (IsEmpty()==true)
{
return LISTDOUBLE_POSITION_INVALID;
}
AL_Node *pMvoe = NULL;
DWORD dwCount = 1;
pMvoe = m_pHeader->m_pNext;
while(pMvoe->m_pNext!=NULL)
{
if (pMvoe->m_data==tTemplate)
{
return dwCount - 1;
}
dwCount++;
pMvoe = pMvoe->m_pNext;
}
if (pMvoe->m_data==tTemplate)
{
return dwCount - 1;
}
return LISTDOUBLE_POSITION_INVALID;
}
template<typename T>
inline bool AL_ListCircuarDouble::IsElement(const T & tTemplate) const
{
if (Find(tTemplate) == LISTDOUBLE_POSITION_INVALID);
{
return false;
}
return true;
}
template<typename T>
inline bool AL_ListCircuarDouble::Insert(DWORD dwIndex, const T & tTemplate)
{
if (dwIndex>Length())
{
return false;
}
AL_Node *pInsert = new AL_Node();
pInsert->m_data = tTemplate;
AL_Node *pPer = NULL;
if (dwIndex==0x00)
{
pPer = m_pHeader;
}
else
{
pPer = GetNodeByIndex(dwIndex - 1);
}
if (pPer==NULL)
{
return false;
}
if (dwIndex==Length())
{
pPer->m_pNext = pInsert;
pInsert->m_pPre = pPer;
pInsert->m_pNext = m_pHeader;
m_pHeader->m_pPre = pInsert;
}
else
{
AL_Node *IndexNode = pPer->m_pNext;
if (IndexNode==NULL)
{
return false;
}
pPer->m_pNext = pInsert;
pInsert->m_pPre = pPer;
pInsert->m_pNext = IndexNode;
IndexNode->m_pPre = pInsert;
}
m_dwSize++;
return true;
}
template<typename T>
inline bool AL_ListCircuarDouble::InsertBegin(const T & tTemplate)
{
return Insert(0x00, tTemplate);
}
template<typename T>
inline bool AL_ListCircuarDouble::InsertEnd(const T & tTemplate)
{
return Insert(Length(),tTemplate);
}
template<typename T>
inline bool AL_ListCircuarDouble::Remove(const T & tTemplate)
{
if (IsEmpty()==true)
{
return false;
}
DWORD dwPosition = Find(tTemplate);
if (dwPosition==LISTDOUBLE_POSITION_INVALID)
{
return false;
}
AL_Node *pDelete =GetNodeByIndex(dwPosition);
if (pDelete==NULL)
{
return false;
}
AL_Node *pPer = NULL;
if (dwPosition==0x00)
{
pPer= m_pHeader;
}
else
{
pPer = pDelete->m_pPre;
}
if (pPer==NULL)
{
return false;
}
pPer->m_pNext = pDelete->m_pNext;
delete pDelete;
pDelete = NULL;
m_dwSize--;
return true;
}
template<typename T>
inline bool AL_ListCircuarDouble::IsEmpty() const
{
//判断是否循环指向头结点。
return (m_pHeader->m_pNext==m_pHeader)?true:false;
}
template<typename T>
inline bool AL_ListCircuarDouble::Get(T & tTypeOut, DWORD dwIndex) const
{
if (IsEmpty() == true)
{
return false;
}
if (dwIndex>Length()-1)
{
return false;
}
AL_Node *pGet = GetNodeByIndex(dwIndex);
if (pGet==NULL)
{
return false;
}
tTypeOut = pGet->m_data;
return true;
}
template<typename T>
inline bool AL_ListCircuarDouble::Set(T & tTypeOut, DWORD dwIndex, const T & tTemplate)
{
if (IsEmpty()==true)
{
return false;
}
if (dwIndex>Length()-1)
{
return false;
}
AL_Node *pSet = GetNodeByIndex(dwIndex);
if (pSet==NULL)
{
return false;
}
tTypeOut = pSet->m_data;
pSet->m_data = tTemplate;
return true;
}
template<typename T>
inline void AL_ListCircuarDouble::Clear()
{
if (IsEmpty()==true)
{
return;
}
AL_Node *pDelete = NULL;
while (m_pHeader->m_pNext!=m_pHeader)
{
pDelete = m_pHeader->m_pNext;
m_pHeader->m_pNext = pDelete->m_pNext;
delete pDelete;
pDelete = NULL;
}
m_dwSize = 0x00;
}
template<typename T>
inline AL_Node* AL_ListCircuarDouble::GetNodeByIndex(DWORD dwIndex) const
{
if (dwIndex>Length()-1)
{
return NULL;
}
AL_Node * pMove = NULL;
DWORD dwCount = 1;
pMove = m_pHeader->m_pNext;
while (pMove->m_pNext!=m_pHeader)
{
if (dwCount-1==dwIndex)
{
return pMove;
}
dwCount++;
pMove = pMove->m_pNext;
}
return pMove;
}
测试代码:
void ListCircularDoubleTest()
{
AL_ListCircuarDouble clistCircuarDouble;
bool bEmpty = clistCircuarDouble.IsEmpty();
std::cout << bEmpty << std::endl;
int arrays[15] = { 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 };
for (int i = 0; i < 15; i++)
{
clistCircuarDouble.Insert(i, arrays[i]);
}
bEmpty = clistCircuarDouble.IsEmpty();
DWORD blength = clistCircuarDouble.Length();
std::cout << bEmpty << " " << blength << std::endl;
bEmpty = clistCircuarDouble.Remove(6);
blength = clistCircuarDouble.Length();
std::cout << bEmpty << " " << blength << std::endl;
DWORD sget, sset;
clistCircuarDouble.Set(sset, 5, 123);
clistCircuarDouble.Get(sget, 5);
std::cout << sset << " " << sget << std::endl;
DWORD sfind = clistCircuarDouble.Find(5);
DWORD sfind1 = clistCircuarDouble.Find(123);
std::cout << sfind1 << " " << sfind << std::endl;
}
int main(int argc, char *argv[])
{
ListCircularDoubleTest();
getchar();
return 0;
}