📄 multilinklist.h
字号:
//------------------------------------------------------------------
//
// FILE : MultiLinkList.h
//
// PURPOSE : Defines the CMultiLinkList class. This is a linked list
// that allows more control over its use, so an object can
// be contained in multiple linked lists.
//
// CREATED : December 1 1996
//
// COPYRIGHT : Microsoft 1996 All Rights Reserved
//
//------------------------------------------------------------------
#ifndef __MULTILINKLIST_H__
#define __MULTILINKLIST_H__
#ifndef ASSERT
#define ASSERT
#endif
#ifndef DWORD
#define DWORD unsigned long
#endif
class CMLLNode
{
public:
CMLLNode *m_pGPrev, *m_pGNext;
void *m_pObject;
};
typedef CMLLNode* MPOS;
template<class T>
class CMultiLinkList
{
protected:
public:
CMultiLinkList()
{
m_nElements = 0;
m_pHead = NULL;
}
~CMultiLinkList()
{
RemoveAll();
}
// Replacement for GetHeadPosition().
operator MPOS() { return m_pHead; }
DWORD GetCount() const { return m_nElements; }
DWORD GetSize() const { return m_nElements; }
int IsEmpty() const { return !m_pHead; }
T GetHead() const;
T GetTail() const;
T RemoveHead();
T RemoveTail();
MPOS AddHead( T newHead, CMLLNode *pLinkInfo );
MPOS AddTail( T newTail, CMLLNode *pLinkInfo );
void RemoveAll();
MPOS GetHeadPosition() const { return m_pHead; }
MPOS GetTailPosition() const { return (m_pHead ? m_pHead->m_pGPrev : NULL); }
T GetNext( MPOS &pos ) const;
T GetPrev( MPOS &pos ) const;
T GetAt( MPOS pos );
void RemoveAt( MPOS pos );
MPOS InsertBefore( MPOS pos, T el, CMLLNode *pLinkInfo );
MPOS InsertAfter( MPOS pos, T el, CMLLNode *pLinkInfo );
MPOS Find( T searchFor, DWORD *pIndex=NULL ) const;
DWORD FindElement( T searchFor, MPOS *pPos=NULL ) const;
MPOS FindIndex( DWORD index ) const;
protected:
DWORD m_nElements;
CMLLNode *m_pHead;
};
template<class T>
T CMultiLinkList<T>::GetHead() const
{
ASSERT(m_pHead);
return (T)m_pHead->m_pObject;
}
template<class T>
T CMultiLinkList<T>::GetTail() const
{
ASSERT(m_pHead);
return (T)m_pHead->m_pGPrev->m_pObject;
}
template<class T>
T CMultiLinkList<T>::GetNext( MPOS &pos ) const
{
T ret = (T)pos->m_pObject;
if( pos->m_pGNext == m_pHead )
pos = NULL;
else
pos = pos->m_pGNext;
return ret;
}
template<class T>
T CMultiLinkList<T>::GetPrev( MPOS &pos ) const
{
T ret = (T)pos->m_pObject;
if( pos->m_pGPrev == m_pHead )
pos = NULL;
else
pos = pos->m_pGPrev;
return ret;
}
template<class T>
T CMultiLinkList<T>::RemoveHead()
{
T ret;
ASSERT( m_pHead );
ret = (T)m_pHead->m_pObject;
RemoveAt( m_pHead );
return ret;
}
template<class T>
T CMultiLinkList<T>::RemoveTail()
{
T ret;
ASSERT( m_pHead );
ret = m_pHead->m_pGPrev->m_pObject;
RemoveAt( m_pHead->m_pGPrev );
return ret;
}
template<class T>
MPOS CMultiLinkList<T>::AddHead( T newHead, CMLLNode *pLinkInfo )
{
if( m_pHead )
{
return InsertBefore( m_pHead, newHead, pLinkInfo );
}
else
{
pLinkInfo->m_pGNext = pLinkInfo;
pLinkInfo->m_pGPrev = pLinkInfo;
pLinkInfo->m_pObject = newHead;
m_pHead = pLinkInfo;
++m_nElements;
return m_pHead;
}
}
template<class T>
MPOS CMultiLinkList<T>::AddTail( T newTail, CMLLNode *pLinkInfo )
{
if( m_pHead )
return InsertAfter( m_pHead->m_pGPrev, newTail, pLinkInfo );
else
return AddHead( newTail, pLinkInfo );
}
template<class T>
void CMultiLinkList<T>::RemoveAll()
{
m_pHead = NULL;
m_nElements = 0;
}
template<class T>
T CMultiLinkList<T>::GetAt( MPOS pos )
{
return (T)pos->m_pObject;
}
template<class T>
void CMultiLinkList<T>::RemoveAt( MPOS pos )
{
ASSERT( m_nElements > 0 );
pos->m_pGPrev->m_pGNext = pos->m_pGNext;
pos->m_pGNext->m_pGPrev = pos->m_pGPrev;
if( pos == m_pHead )
m_pHead = m_pHead->m_pGNext;
--m_nElements;
if( m_nElements == 0 )
m_pHead = NULL;
}
template<class T>
MPOS CMultiLinkList<T>::InsertBefore( MPOS pos, T el, CMLLNode *pLinkInfo )
{
pos->m_pGPrev->m_pGNext = pLinkInfo;
pLinkInfo->m_pGPrev = pos->m_pGPrev;
pLinkInfo->m_pGNext = pos;
pos->m_pGPrev = pLinkInfo;
pLinkInfo->m_pObject = el;
++m_nElements;
if( pLinkInfo->m_pGNext == m_pHead )
m_pHead = pLinkInfo;
return pLinkInfo;
}
template<class T>
MPOS CMultiLinkList<T>::InsertAfter( MPOS pos, T el, CMLLNode *pLinkInfo )
{
pos->m_pGNext->m_pGPrev = pLinkInfo;
pLinkInfo->m_pGNext = pos->m_pGNext;
pLinkInfo->m_pGPrev = pos;
pos->m_pGNext = pLinkInfo;
pLinkInfo->m_pObject = el;
++m_nElements;
return pLinkInfo;
}
template<class T>
MPOS CMultiLinkList<T>::Find( T searchFor, DWORD *pIndex ) const
{
CMLLNode *pCur;
DWORD index=0;
if( m_pHead )
{
pCur = m_pHead;
do
{
if( (T)pCur->m_pObject == searchFor )
{
if( pIndex )
*pIndex = index;
return pCur;
}
pCur = pCur->m_pGNext;
++index;
} while( pCur != m_pHead );
}
if( pIndex )
*pIndex = BAD_INDEX;
return NULL;
}
template<class T>
DWORD CMultiLinkList<T>::FindElement( T searchFor, MPOS *pPos ) const
{
MPOS pos;
DWORD index;
pos = Find( searchFor, &index );
if( pPos )
*pPos = pos;
return index;
}
template<class T>
MPOS CMultiLinkList<T>::FindIndex( DWORD index ) const
{
CMLLNode *pCur;
if( index >= m_nElements )
return NULL;
pCur = m_pHead;
do
{
if( index == 0 )
return pCur;
pCur = pCur->m_pGNext;
--index;
} 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 MDeleteAndRemoveElements(CMultiLinkList<T> &theList)
{
MPOS pos;
for( pos=theList.GetHeadPosition(); pos != NULL; )
delete theList.GetNext(pos);
theList.RemoveAll();
}
#endif // __MULTILINKLIST_H__
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -