#pragma once
#define SAFE_DELETE(p) if(p!=NULL) { delete p; p= NULL; }
#define SAFE_DELETE_ARRAY(p) if(p!=NULL) { delete [] p; p= NULL; }
template <typename T>
//< 노드 설정
struct NODE
{
//< 노드
NODE* pNext;
NODE* pPrev;
//< 엘리먼트
T nData;
};
template <typename T>
class cMylist
{
private:
private:
//< 머리 ( 리스트의 처음 위치를 저장 )
NODE<T>* m_pHeader;
//< 꼬리 ( 리스트의 맨 끝 위치를 저장 )
NODE<T>* m_pTail;
//< 노드의 갯수
int m_nNodeCount;
public:
cMylist(void);
~cMylist(void);
//< 넣기
//< 맨앞에 넣기
void push_front( T nData );
//< 맨뒤에 넣기
void push_back( T nData );
//< 빼기
//< 맨앞에 빼기
T pop_front( void );
//< 맨뒤에 빼기
T pop_back( void );
//< 전체 삭제( 완전히 지우기 )
void remove_all( void );
//< 노드들만 지우기( Head와 tail은 제외 )
void reset_list( void );
//< 찾기
//< 데이터로 찾기
NODE<T>* find( T nData );
//< 출력
void OutputList( void );
//< 노드 개수
int size( void )
{
return m_nNodeCount;
}
private:
//< 노드 생성
NODE<T>* createNode( T nData );
//< 초기화
void InitList( void );
};
template <typename T>
cMylist<T>::cMylist(void)
:m_pHeader( NULL ),m_pTail( NULL ), m_nNodeCount( 0 )
{
//< 초기화
InitList();
}
template <typename T>
cMylist<T>::~cMylist(void)
{
//< 삭제
remove_all();
InitList();
}
//< 초기화
template <typename T>
void cMylist<T>::InitList( void )
{
//< 헤더 / 테일 할당
m_pHeader = new NODE<T>;
m_pTail = new NODE<T>;
//< 연결
m_pHeader->pNext = m_pTail;
m_pHeader->pPrev = NULL;
m_pTail->pPrev = m_pHeader;
m_pTail->pNext = NULL;
//< 갯수
m_nNodeCount = 0;
}
//< 넣기
//< 맨앞에 넣기
template <typename T>
void cMylist<T>::push_front( T nData )
{
NODE<T>* pNew = createNode( nData );
//< 신규 노드 처리
pNew->pNext = m_pHeader->pNext;
pNew->pPrev = m_pHeader;
//< 헤더 처리
m_pHeader->pNext->pPrev = pNew;
m_pHeader->pNext = pNew;
//< 노드 증가
m_nNodeCount++;
}
//< 맨뒤에 넣기
template <typename T>
void cMylist<T>::push_back( T nData )
{
NODE<T>* pNew = createNode( nData );
//< 신규 노드 처리
pNew->pNext = m_pTail;
pNew->pPrev = m_pTail->pPrev;
//< 꼬리 처리
m_pTail->pPrev->pNext = pNew;
m_pTail->pPrev = pNew;
//< 노드 증가
m_nNodeCount++;
}
//< 빼기
//< 맨앞에 빼기
template <typename T>
T cMylist<T>::pop_front( void )
{
T nResult = 0;
if( m_pHeader->pNext != m_pTail )
{
//< 연결후 반환
NODE<T>* pBack = m_pHeader->pNext;
//< 연결
m_pHeader->pNext = pBack->pNext;
pBack->pNext->pPrev = m_pHeader;
//< 반환 데이터 백업 및 삭제
nResult = pBack->nData;
SAFE_DELETE( pBack);
//< 노드감소
m_nNodeCount--;
return nResult;
}
return nResult;
}
//< 맨뒤에 빼기
template <typename T>
T cMylist<T>::pop_back( void )
{
T nResult = 0;
if( m_pTail->pPrev != m_pHeader )
{
//< 연결후 반환
NODE<T>* pBack = m_pTail->pPrev;
//< 연결
m_pTail->pPrev = pBack->pPrev;
pBack->pPrev->pNext = m_pTail;
//< 반환 데이터 백업 및 삭제
T nResult = pBack->nData;
SAFE_DELETE( pBack);
//< 노드감소
m_nNodeCount--;
return nResult;
}
return -1;
}
//< 전체 삭제( 완전히 지우기 )
template <typename T>
void cMylist<T>::remove_all( void )
{
//< 모두지우기 (데이터 )
reset_list();
//< 헤더와 tail을 지우기
SAFE_DELETE(m_pHeader);
//< NULL처리
SAFE_DELETE(m_pTail);
InitList();
}
//< 노드들만 지우기( Head와 tail은 제외 )
template <typename T>
void cMylist<T>::reset_list( void )
{
if( m_pHeader != NULL )
{
NODE<T>* pHead = m_pHeader->pNext;
while( pHead != m_pTail )
{
//< 지우기 전에 보관
NODE<T>* pBack = pHead->pNext;
//< 지우기
SAFE_DELETE(pHead);
m_nNodeCount--;
//< 다음꺼
pHead = pBack;
}
InitList();
}
}
//< 찾기
//< 데이터로 찾기
template <typename T>
NODE<T>* cMylist<T>::find( T nData )
{
if( m_nNodeCount == 0 )
{
cout <<"데이터가 없습니다." << endl;
return NULL;
}
NODE<T>* pHead = m_pHeader->pNext;
//< 돌기
while( pHead != m_pTail )
{
if( pHead->nData == nData )
{
return pHead;
}
//< 다음
pHead = pHead->pNext;
}
cout <<"해당 데이터가 없습니다." << endl;
return NULL;
}
//< 출력
template <typename T>
void cMylist<T>::OutputList( void )
{
cout << "현재 노드 개수: " << m_nNodeCount << endl;
NODE<T>* pHead = m_pHeader->pNext;
//< 돌기
while( pHead != m_pTail )
{
cout << pHead->nData << " ";
//< 다음
pHead = pHead->pNext;
}
}
//< 노드 생성
template <typename T>
NODE<T>* cMylist<T>::createNode( T nData )
{
NODE<T>* pNewNode = new NODE<T>;
pNewNode->nData = nData;
pNewNode->pNext = NULL;
pNewNode->pPrev = NULL;
return pNewNode;
}
int _tmain(int argc, _TCHAR* argv[])
{
cMylist<char*> dList;
//< 앞에 넣기
dList.push_front("a");
dList.push_front("b");
//< 뒤에 넣기
dList.push_back("c");
dList.push_back("d");
NODE<char*>* pFind = dList.find("a");
if( pFind != NULL )
{
cout << pFind->nData << endl;
}
//< 출력 테스트
dList.OutputList();
return 0;
}