在单链表中,有了头结点,我们可以在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; };