#ifndef _LINKED_LIST_H_ #define _LINKED_LIST_H_ /****************************************************************** * * wyLib库 2008 - 2010 * * $ 链表类 $ * * - 主要功能 - * * 实现动态添加、插入节点。与CBaseList一样,链表类也是一个容器类,但与 * CBaseList比较,链表在进行删除节点的时候能够更大的发挥效率,缺点则是比列表 * 更加浪费内存(内存开销为3~4倍)且在按索引访问的时候效率极低。 * *****************************************************************/ #include "ObjectCounter.h" #include "TypeDef.h" #include "_ast.h" namespace wylib { namespace container { template class CBaseLinkedList; template class CLinkedListIterator; /************************* * 链表节点类 **************************/ template class CLinkedNode : public Counter > { friend class CBaseLinkedList; friend class CLinkedListIterator; public: typedef T InstancesType; public: inline operator T& (){ return m_Data; } inline CLinkedNode* prev(){ return m_pPrevNode; } inline CLinkedNode* next(){ return m_pNextNode; } inline CBaseLinkedList* list(){ return m_pOwnList; } T m_Data; private: CLinkedNode* m_pPrevNode; CLinkedNode* m_pNextNode; CBaseLinkedList* m_pOwnList; }; /************************* * 链表迭代器类 **************************/ template class CLinkedListIterator { friend class CBaseLinkedList; public: CLinkedListIterator() { m_pList = NULL; m_pEnuming = NULL; m_pPrevIterator = m_pNextIterator = NULL; } CLinkedListIterator(CBaseLinkedList &list) { m_pList = NULL; m_pEnuming = NULL; m_pPrevIterator = m_pNextIterator = NULL; setList(list); } ~CLinkedListIterator() { if (m_pList) { if (m_pPrevIterator) m_pPrevIterator->m_pNextIterator = m_pNextIterator; if (m_pNextIterator) m_pNextIterator->m_pPrevIterator = m_pPrevIterator; if (this == m_pList->m_pLastIterator) m_pList->m_pLastIterator = m_pPrevIterator; m_pList = NULL; m_pEnuming = NULL; m_pPrevIterator = m_pNextIterator = NULL; } } //重新设置遍历对象 inline VOID setList(CBaseLinkedList &list) { this->~CLinkedListIterator(); m_pList = &list; m_pEnuming = NULL; m_pNextIterator = NULL; m_pPrevIterator = list.m_pLastIterator; if (m_pPrevIterator) m_pPrevIterator->m_pNextIterator = this; list.m_pLastIterator = this; } //移除一个节点,方便在迭代的过程中移除节点从而破坏迭代过程 inline void remove(CLinkedNode* pNode, BOOL boFree = TRUE) { if (pNode == m_pEnuming) m_pEnuming = pNode->m_pPrevNode; m_pList->remove(pNode, boFree); } //从头开始遍历节点 inline CLinkedNode* first(){ return m_pEnuming = m_pList->first(); } //遍历下一个节点 inline CLinkedNode* next(){ return m_pEnuming = (m_pEnuming ? m_pEnuming->m_pNextNode : m_pList->first()); } //当前遍历到的节点 inline CLinkedNode* current(){ return m_pEnuming; }; private: CLinkedNode* m_pEnuming; CBaseLinkedList* m_pList; CLinkedListIterator* m_pPrevIterator; CLinkedListIterator* m_pNextIterator; }; /************************* * 链表类 **************************/ template class CBaseLinkedList { friend class CLinkedListIterator; public: typedef T InstancesType; typedef CLinkedNode NodeType; typedef CLinkedListIterator Iterator; public: CBaseLinkedList() { m_pFirst = m_pLast = NULL; m_pLastIterator = NULL; m_nNodeCount = 0; } virtual ~CBaseLinkedList() { clear(); } //获取第一个节点 inline CLinkedNode* first(){ return m_pFirst; } //获取最后一个节点 inline CLinkedNode* last(){ return m_pLast; } //获取节点数量 inline INT_PTR count() const { return m_nNodeCount; } /* 在pNode节点的前面插入新节点 * 如果pNode为空则表示插入到链表的起始位置 */ CLinkedNode * linkBefore(const T& data, CLinkedNode *pNode = NULL) { Assert(!pNode || pNode->m_pOwnList == this); if ( !pNode ) pNode = m_pFirst; CLinkedNode *pPrev = pNode ? pNode->m_pPrevNode : NULL; CLinkedNode *pNewNode = allocNode(); pNewNode->m_Data = data; pNewNode->m_pPrevNode = pPrev; pNewNode->m_pNextNode = pNode; if ( pPrev ) pPrev->m_pNextNode = pNewNode; else m_pFirst = pNewNode; if ( pNode ) pNode->m_pPrevNode = pNewNode; else m_pLast = pNewNode; pNewNode->m_pOwnList = this; m_nNodeCount++; return pNewNode; } /* 在pNode节点的后面插入新节点 * 如果pNode为空则表示插入到链表的末尾 */ CLinkedNode * linkAfter(const T& data, CLinkedNode *pNode = NULL) { //Assert(!pNode || pNode->m_pOwnList == this); if ( !pNode ) pNode = m_pLast; CLinkedNode *pNext = pNode ? pNode->m_pNextNode : NULL; CLinkedNode *pNewNode = allocNode(); pNewNode->m_Data = data; pNewNode->m_pPrevNode = pNode; pNewNode->m_pNextNode = pNext; if ( pNext ) pNext->m_pPrevNode = pNewNode; else m_pLast = pNewNode; if ( pNode ) pNode->m_pNextNode = pNewNode; else m_pFirst = pNewNode; pNewNode->m_pOwnList = this; m_nNodeCount++; return pNewNode; } //重载linkAfer,插入一个已有的node CLinkedNode * Transfer(CLinkedNode *pNewNode, CLinkedNode *pNode = NULL) { Assert(!pNode || pNode->m_pOwnList == this); Assert(pNewNode->m_pOwnList == NULL); if ( !pNode ) pNode = m_pLast; CLinkedNode *pNext = pNode ? pNode->m_pNextNode : NULL; pNewNode->m_pPrevNode = pNode; pNewNode->m_pNextNode = pNext; if ( pNext ) pNext->m_pPrevNode = pNewNode; else m_pLast = pNewNode; if ( pNode ) pNode->m_pNextNode = pNewNode; else m_pFirst = pNewNode; pNewNode->m_pOwnList = this; m_nNodeCount++; return pNewNode; } //将数据插入到链表头部 inline CLinkedNode* linkAtFirst(const T& data) { return inkBefore(data, m_pFirst); } //将数据添加到链表尾部 inline CLinkedNode* linkAtLast(const T& data) { return linkAfter(data, m_pLast); } inline CLinkedNode* TransferAtLast(CLinkedNode *pNewNode) { return Transfer(pNewNode, m_pLast); } //通过索引获取链表节点 CLinkedNode *getNodeAt(INT_PTR nIndex) { for (CLinkedNode *pNode = m_pFirst; pNode; pNode = pNode->m_pNextNode) { if ( nIndex <= 0 ) return pNode; nIndex--; } return NULL; } /* 移除一个链表节点 * ★注意★ 如果正在通过迭代器遍历链表,则移除操作必须调用迭代器的CLinkedListIterator::remove函数 */ inline VOID remove(CLinkedNode *pNode,BOOL boFree=TRUE) { if ( pNode && pNode->m_pOwnList == this ) { //移除节点 if ( pNode->m_pPrevNode ) pNode->m_pPrevNode->m_pNextNode = pNode->m_pNextNode; if ( pNode->m_pNextNode ) pNode->m_pNextNode->m_pPrevNode = pNode->m_pPrevNode; if ( pNode == m_pFirst ) m_pFirst = pNode->m_pNextNode; if ( pNode == m_pLast ) m_pLast = pNode->m_pPrevNode; //从所有迭代器中测试并修正当前遍历节点 if (m_pLastIterator) { Iterator *pIt = m_pLastIterator; while (pIt) { if (pNode == pIt->m_pEnuming) pIt->m_pEnuming = pNode->m_pPrevNode; //修复了如果迭代器本身出现问题的时候,可能引起死循环的问题 if(pIt->m_pPrevIterator != pIt) { pIt = pIt->m_pPrevIterator; } else { break; } } } pNode->m_pOwnList = NULL; //销毁节点 if (boFree) freeNode(pNode); m_nNodeCount--; #ifdef WIN32 Assert(m_nNodeCount >= 0); #endif } } //清空链表 virtual VOID clear() { CLinkedNode *pNode = m_pFirst, *pNextNode; while ( pNode ) { pNextNode = pNode->m_pNextNode; freeNode(pNode); pNode = pNextNode; } m_pFirst = m_pLast = NULL; m_nNodeCount = 0; } protected: /* 申请一个链表节点对象,默认的操作时使用new申请内存并构造 * 子类可通过覆盖此方法实现链表节点的内存管理 */ virtual CLinkedNode* allocNode() { return new CLinkedNode; } /* 销毁一个链表节点对象,默认的操作时使用delete析构并释放内存 * 子类可通过覆盖此方法实现链表节点的内存管理 */ virtual VOID freeNode(CLinkedNode *pNode) { delete pNode; } private: CLinkedNode *m_pFirst; CLinkedNode *m_pLast; Iterator *m_pLastIterator; INT_PTR m_nNodeCount; }; }; }; #endif