본문 바로가기
카테고리 없음

템플릿 리스트 구현

by ByteBridge 2013. 3. 23.
반응형

#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;

}

반응형