⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 linklist.h

📁 Blood 2全套源码
💻 H
字号:
#ifndef __LINKLIST_H__
#define __LINKLIST_H__


	#include "struct_bank.h"

	#ifndef ASSERT
		#define ASSERT
	#endif

	#ifndef DWORD
		#define DWORD	unsigned long
	#endif

	typedef void*	LPOS;


	template<class T>
	class CLLNode
	{
		public:
			
			CLLNode<T>		*m_pPrev;
			CLLNode<T>		*m_pNext;
			T				m_pData;
	};

	
	extern StructBank g_LinkListBank;
	extern int g_LinkListRefCount;



	template<class T>
	class CLinkedList
	{
		protected:
			
				
		
		public:

						CLinkedList()
						{
							if(g_LinkListRefCount == 0)
							{
								sb_Init(&g_LinkListBank, sizeof(CLLNode<T>), 50);
							}

							++g_LinkListRefCount;
							m_nElements = 0;
							m_pHead = NULL;
						}

						~CLinkedList()
						{
							RemoveAll();

							--g_LinkListRefCount;
							if(g_LinkListRefCount == 0)
							{
								sb_Term(&g_LinkListBank);
							}
						}

			
			DWORD		GetSize() const		{ return m_nElements; }
			DWORD		GetCount() const		{ return m_nElements; }
			int			IsEmpty()  const		{ return !m_pHead; }

						operator LPOS() {return GetHeadPosition();}
						operator unsigned long() {return m_nElements;}

			T&			GetHead()				{ ASSERT(m_pHead);  return m_pHead->m_pData; }
			T			GetHead()	const		{ ASSERT(m_pHead);  return m_pHead->m_pData; }
			T&			GetTail()				{ ASSERT(m_pHead);	return m_pHead->m_pPrev->m_pData; }
			T			GetTail()	const		{ ASSERT(m_pHead);	return m_pHead->m_pPrev->m_pData; }

			T			RemoveHead();
			T			RemoveTail();

			LPOS		Append(T toAppend) {return AddTail(toAppend);}

			LPOS		AddHead( T newHead );
			LPOS		AddTail( T newTail );

			void		RemoveAll();

			LPOS			GetHeadPosition()	const	{ return m_pHead; }
			LPOS			GetTailPosition()	const	{ return (m_pHead ? m_pHead->m_pPrev : NULL); }

			T&			GetNext( LPOS &lPos )
			{
				CLLNode<T>		**pNode = (CLLNode<T>**)&lPos;
				T				&ret = (*pNode)->m_pData;

				if( (*pNode)->m_pNext == m_pHead )
					*pNode = NULL;
				else
					*pNode = (*pNode)->m_pNext;

				return ret;
			}

			T			GetNext( LPOS &lPos )	const
			{
				CLLNode<T>		**pFirstNode = (CLLNode<T>**)&lPos;
				CLLNode<T>		**pNode = pFirstNode;
				
				if( (*pNode)->m_pNext == m_pHead )
					*pNode = NULL;
				else
					*pNode = (*pNode)->m_pNext;

				return (*pFirstNode)->m_pData;
			}

			T&			GetPrev( LPOS &lPos )
			{
				CLLNode<T>		**pNode = (CLLNode<T>**)&lPos;
				T				&ret = (*pNode)->m_pData;

				if( (*pNode)->m_pPrev == m_pHead )
					*pNode = NULL;
				else
					*pNode = (*pNode)->m_pPrev;

				return ret;
			}
			
			T			GetPrev( LPOS &lPos )	const
			{
				CLLNode<T>		**pFirstNode = (CLLNode<T>**)&lPos;
				CLLNode<T>		**pNode = pFirstNode;

				if( (*pNode)->m_pPrev == m_pHead )
					*pNode = NULL;
				else
					*pNode = (*pNode)->m_pPrev;

				return (*pFirstNode)->m_pData;
			}

			T&			GetAt( LPOS &lPos )			{ return ((CLLNode<T>*)lPos)->m_pData; }
			T			GetAt( LPOS &lPos )	const	{ return ((CLLNode<T>*)lPos)->m_pData; }
			
			void		SetAt( LPOS &lPos, T el )		{ ((CLLNode<T>*)lPos)->m_pData = el; }
			void		RemoveAt( LPOS lPos );

			LPOS			InsertBefore( LPOS lPos, T el );
			LPOS			InsertAfter( LPOS lPos, T el );

			LPOS			Find( T searchFor )			const;
			LPOS			FindIndex( DWORD index )	const;




		protected:

			DWORD		m_nElements;
			CLLNode<T>	*m_pHead;

	};


	
	template<class T>
	T CLinkedList<T>::RemoveHead()
	{
		T	ret;

		ASSERT( m_pHead );
		ret = m_pHead->m_pData;
		RemoveAt( m_pHead );
		
		return ret;
	}


	template<class T>
	T CLinkedList<T>::RemoveTail()
	{
		T	ret;

		ASSERT( m_pHead );
		ret = m_pHead->m_pPrev->m_pData;
		RemoveAt( m_pHead->m_pPrev );
		
		return ret;
	}

	
	template<class T>
	LPOS CLinkedList<T>::AddHead( T newHead )
	{
		CLLNode<T>	*pNew = (CLLNode<T>*)sb_Allocate(&g_LinkListBank);

		pNew->m_pData = newHead;
		if( m_pHead )
		{
			pNew->m_pNext = m_pHead;
			pNew->m_pPrev = m_pHead->m_pPrev;
			m_pHead->m_pPrev = pNew;
		}
		else
		{
			pNew->m_pNext = pNew;
			pNew->m_pPrev = pNew;
		}

		m_pHead = pNew;
		++m_nElements;

		return m_pHead;
	}


	template<class T>
	LPOS CLinkedList<T>::AddTail( T newTail )
	{
		if( m_pHead )
			return InsertAfter( (LPOS)m_pHead->m_pPrev, newTail );
		else
			return AddHead( newTail );
	}


	template<class T>
	void CLinkedList<T>::RemoveAll()
	{
		CLLNode<T>	*pCur, *pNext;

		if( m_pHead )
		{
			pCur = m_pHead;
			do
			{
				pNext = pCur->m_pNext;
				sb_Free(&g_LinkListBank, pCur);
				pCur = pNext;
			} while( pCur != m_pHead );
				
			m_nElements = 0;
			m_pHead = NULL;
		}
	}


	template<class T>
	void CLinkedList<T>::RemoveAt( LPOS pos )
	{
		CLLNode<T>		*pNode = (CLLNode<T>*)pos;

		ASSERT( m_nElements > 0 );
		
		pNode->m_pPrev->m_pNext = pNode->m_pNext;
		pNode->m_pNext->m_pPrev = pNode->m_pPrev;
		
		if( pos == m_pHead )
			m_pHead = m_pHead->m_pNext;

		sb_Free(&g_LinkListBank, pNode);
		--m_nElements;

		if( m_nElements == 0 )
			m_pHead = NULL;
	}
	

	template<class T>
	LPOS CLinkedList<T>::InsertBefore( LPOS lPos, T el )
	{
		CLLNode<T>	*pNode = (CLLNode<T>*)lPos;
		CLLNode<T>	*pNew = (CLLNode<T>*)sb_Allocate(&g_LinkListBank);

		pNew->m_pData = el;
		pNew->m_pNext = pNode;
		pNew->m_pPrev = pNode->m_pPrev;
		pNew->m_pPrev->m_pNext = pNew->m_pNext->m_pPrev = pNew;
		
		++m_nElements;
		if( pNew->m_pNext == m_pHead )
			m_pHead = pNew;

		return pNew;
	}


	template<class T>
	LPOS CLinkedList<T>::InsertAfter( LPOS lPos, T el )
	{
		CLLNode<T>	*pNode = (CLLNode<T>*)lPos;
		CLLNode<T>	*pNew = (CLLNode<T>*)sb_Allocate(&g_LinkListBank);

		pNew->m_pData = el;
		pNew->m_pNext = pNode->m_pNext;
		pNew->m_pPrev = pNode;
		pNew->m_pPrev->m_pNext = pNew->m_pNext->m_pPrev = pNew;
		
		++m_nElements;
		return pNew;
	}


	template<class T>
	LPOS CLinkedList<T>::Find( T searchFor )			const
	{
		CLLNode<T>	*pCur;
		
		if( m_pHead )
		{
			pCur = m_pHead;
			do
			{
			
				if( pCur->m_pData == searchFor )
					return pCur;

				pCur = pCur->m_pNext;
			
			} while( pCur != m_pHead );
		}

		return NULL;
	}


	template<class T>
	LPOS CLinkedList<T>::FindIndex( DWORD index )	const
	{
		CLLNode<T>	*pCur;
		
		if( index >= m_nElements )
			return NULL;
	
		pCur = m_pHead;
		do
		{
		
			if( --index == 0 )
				return pCur;

			pCur = pCur->m_pNext;

		} while( pCur != m_pHead );
	
		ASSERT( FALSE );	// Shouldn't ever get here.
		return NULL;
	}




	// Useful template function if your linked list is made up of pointers.
	template<class T>
	void DeleteAndRemoveElements(CLinkedList<T> &theList)
	{
		LPOS lPos;

		for( lPos=theList.GetHeadPosition(); lPos != NULL; )
			delete theList.GetNext(lPos);

		theList.RemoveAll();
	}


#endif // __LINKLIST_H__
	





⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -