在单链表中,有了头结点,我们可以在O(1)时间访问到第一个节点,但如果要访问最后一个节点却需要O(n)的时间,因为我们需要对整个链表进行一次遍历。在循环链表中,我们可以借助尾节点来实现,即不用头指针,而是用指向终端结点的尾指针来表示循环链表,这时候无论是查找第一个节点还是最后一个节点都很方便,可以控制在O(1)的时间内,如下图所示。

 数据结构之循环链表

二 代码实现

(1)循环链表初始化

template <typename T>
struct Node
{
    T data;
    Node<T>* pNext;
};

void InitList()
{
    // 删除所有节点
    Clear();
    m_pHead = new Node<T>;
    memset(m_pHead,0, sizeof(Node<T>));
    m_pHead->pNext = m_pHead;
}        

(2)循环链表新结点插入

// 从尾部添加节点
void AddNode(T data)
{
    Node<T> *pNode = new Node<T>;
    pNode->data = data;

    Node<T>* pTemp = m_pHead;
    while (pTemp->pNext!= m_pHead)
    {
        pTemp = pTemp->pNext;
    }
    pNode->pNext = pTemp->pNext;
    pTemp->pNext = pNode;
}

(3)循环链接结点删除

void DeleteNode(T data)
{
    Node<T> *pNode = m_pHead;
    Node<T> *pTemp = NULL;

    while (pNode->pNext != m_pHead)
    {
        if (pNode->pNext->data == data)
        {
            pTemp = pNode->pNext;
            pNode->pNext = pTemp->pNext;
            delete pTemp;
        }
        else
        {
            pNode = pNode->pNext;
        }
    }
}

(4)删除循环链表

void Clear()
{
    if (NULL == m_pHead)
    {
        return;
    }

    Node<T>* pTemp = NULL;
    Node<T>* pNode = m_pHead->pNext;
    while (pNode != m_pHead)
    {
        pTemp = pNode;
        pNode = pNode->pNext;
        delete pTemp;
    }

    delete pNode;

(5)打印循环链表

void PrintList()
{
    Node<T>* pNode = m_pHead->pNext;
    while (pNode != m_pHead)
    {
        cout << pNode->data << " ";
        pNode = pNode->pNext;
    }

    cout << endl;
}

(6)代码

#include "stdio.h"
#include <iostream>
using namespace std;

template <typename T>
struct Node
{
    T data;
    Node<T>* pNext;
};

// 主要实现循环链表的添加、删除和打印
template <typename T>
class CircList
{
public:
    CircList()
    {
        m_pHead = NULL;
        nLen = 0;
    }
    ~CircList()
    {
        Clear();
        m_pHead = NULL;
    }
    
    void InitList()
    {
        // 删除所有节点
        Clear();
        m_pHead = new Node<T>;
        memset(m_pHead,0, sizeof(Node<T>));
        m_pHead->pNext = m_pHead;
    }
    // 从尾部添加节点
    void AddNode(T data)
    {
        Node<T> *pNode = new Node<T>;
        pNode->data = data;

        Node<T>* pTemp = m_pHead;
        while (pTemp->pNext!= m_pHead)
        {
            pTemp = pTemp->pNext;
        }
        pNode->pNext = pTemp->pNext;
        pTemp->pNext = pNode;

        nLen ++; 
    }
    void DeleteNode(T data)
    {
        Node<T> *pNode = m_pHead;
        Node<T> *pTemp = NULL;

        while (pNode->pNext != m_pHead)
        {
            if (pNode->pNext->data == data)
            {
                pTemp = pNode->pNext;
                pNode->pNext = pTemp->pNext;
                delete pTemp;
            }
            else
            {
                pNode = pNode->pNext;
            }
        }

        nLen --;
    }

    void PrintList()
    {
        Node<T>* pNode = m_pHead->pNext;
        while (pNode != m_pHead)
        {
            cout << pNode->data << " ";
            pNode = pNode->pNext;
        }
    }

    void Clear()
    {
        if (NULL == m_pHead)
        {
            return;
        }

        Node<T>* pTemp = NULL;
        Node<T>* pNode = m_pHead->pNext;
        while (pNode != m_pHead)
        {
            pTemp = pNode;
            pNode = pNode->pNext;
            delete pTemp;
            nLen --;
        }

        delete pNode;
        nLen --;
    }

    Node<T>* ListHead()
    {
        return m_pHead;
    }

    int ListLength()
    {
        return nLen;
    }
    
private: 
    Node<T>* m_pHead;
    int nLen;
};
View Code

相关文章: