数据结构之线性结构 --循环单链表

一、循环链表的简介

循环链表在单链表的基础上使最后的一个节点的指针指向开始的节点形成一个循环的数据结构体,没有空指针的出现。

循环链表在操作上和单链表差不多,单需要注意的是最后一个节点的指针用于时指向头结点的地址的。

二、循环链表的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;
}

运行结果 :

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值