홍열
2012. 11. 18. 13:20
오랜만에 포스팅입니다.
오늘은 LinkedList로 만든 Queue입니다.
Queue는 우리 일상 생활에도 많이 존재합니다.
예를 들어서 은행에서 먼저 온사람이 먼저 서비스 받고, 나중에 온 사람이 나중에 서비스 받는 구조입니다.
즉, 선입선출의 특성을 지닙니다.(First - In - First - Out , FIFO) 먼저 들어온게 먼저 나가고, 나중에 들어온게 나중에 서비스를 받습니다.
Queue를 구현하는 방법은 많이 있습니다만, 저는 여기서 LinkedList를 가지고 구현해보도록 하겠습니다.(이유는 배열로 구현한 것은 미리 Queue의 크기를 정해야 하지만 LinkedList는 그럴 필요 없기 때문입니다. 또 한가지 이유는 제가 요즘 포인터에 대해서 좀 더 친숙해 질려고 노력중이기 때문입니다.)
Queue를 그림으로 표현하면 다음과 같이 표현합니다.
Queue에는 포인터가 2개가 존재합니다. 맨 처음을 가르키는 포인터와 맨 끝을 가르키는 포인터
enQueue는 Data를 집어 넣는 것이고, deQueue는 Data를 빼는 것입니다.
enQueue시에는 rearNode를 한단계 증가시켜주면 되고,
deQueue에는 frontNode를 한단계 증가시키고 메모리를 해제하면 되겠습니다.
linkedQueue.h
더보기 접기
#ifndef _LINKED_QUEUE_
#define _LINKED_QUEUE_
typedef struct QueueNodeType
{
char data;
struct QueueNodeType* pLink;
} QueueNode; //큐노드 구조체
typedef struct LinkedQueueType
{
int currentElementCount;
QueueNode* pFrontQueue;
QueueNode* pRearQueue;
} LinkedQueue; //큐 구조체
LinkedQueue* createLinkedQueue( ) ; //큐 생성 함수
int edqueueLQ( LinkedQueue* pQueue, QueueNode element) ; //큐에 값을 넣는 함수
QueueNode* dequeueLQ( LinkedQueue* pQueue) ; //큐에 값을 빼는 함수
QueueNode* peekLQ( LinkedQueue* pQueue) ; //큐의 맨 앞의 값, 즉 frontNode의 값을 가져온다
void deleteLinkedQueue( LinkedQueue* pQueue) ; //큐 삭제 함수
int isLinkedQueueFull( LinkedQueue* pQueue) ; //큐가 다 찼는지 검사
int isLinkedQueueEmpty( LinkedQueue* pQueue) ; //큐가 비어있는지 검사
#endif
#ifndef _COMMON_QUEUE_DEF_
#define _COMMON_QUEUE_DEF_
#define TRUE 1
#define FALSE 0
#endif
접기
linkedQueue.cpp
더보기 접기
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#include "linkedqueue.h"
LinkedQueue* createLinkedQueue( )
{
LinkedQueue* pReturn = NULL ; //새로 LinkedQueue를 생성한다.
int i = 0 ;
pReturn = ( LinkedQueue* ) malloc ( sizeof ( LinkedQueue) ) ; //메모리를 할당하고
if ( pReturn ! = NULL )
{
memset ( pReturn, 0 , sizeof ( LinkedQueue) ) ; //메모리가 제대로 할당 되었다면 메모리를 0으로 채운다.
}
else
{
printf ( "memory error, createLinkedQueue()\n " ) ;
}
return pReturn; //pReturn값이 NULL 혹은 제대로 메모리 할당 한 값을 반환한다.
}
int edqueueLQ( LinkedQueue* pQueue, QueueNode element)
{ //큐에 데이터를 넣는 함수
int ret = FALSE;
QueueNode* pNode; //큐에서 연결할 수 있는 구조체
if ( pQueue! = NULL )
{
pNode = ( QueueNode* ) malloc ( sizeof ( QueueNode) ) ; //메모리 할당하고
if ( pNode! = NULL )
{
* pNode = element; //할당이 잘 되었다면 element값을 넣어준다.
//pNode = &(element); //이렇게 해줘도 상관없다.
pNode- > pLink = NULL ;
//만약 Queue가 비어있다면 FrontNode 와 RearNode가 같은 값을 가지고 있따.
if ( isLinkedQueueEmpty( pQueue) == TRUE)
{
pQueue- > pFrontQueue = pNode;
pQueue- > pRearQueue = pNode;
}
else
{
//그렇지 않으면 RearNode->pLink에만 pNode를 연결시켜준다
pQueue- > pRearQueue- > pLink = pNode;
pQueue- > pRearQueue = pNode;
}
pQueue- > currentElementCount++ ;
ret = TRUE;
}
else
{
printf ( "memory error, enqueue()\n " ) ;
}
}
return ret;
}
QueueNode* dequeueLQ( LinkedQueue* pQueue)
{ //Queue의 FrontNode를 가져오는 함수
QueueNode* pReturn = NULL ;
if ( pQueue ! = NULL )
{
pReturn = ( QueueNode* ) malloc ( sizeof ( QueueNode) ) ;
//Queue가 비었는지 검사를 하고
if ( isLinkedQueueEmpty( pQueue) == FALSE)
{
//pReturn에 pQueue의 pFrontQueue를 넣어준다.
//그리고 pQueue의 pFrontQueue에 다음 주소값을 대입해주고
//pReturn을 삭제한다.
pReturn = pQueue- > pFrontQueue;
pQueue- > pFrontQueue = pQueue- > pFrontQueue- > pLink;
pReturn- > pLink = NULL ;
pQueue- > currentElementCount-- ;
if ( isLinkedQueueEmpty( pQueue) == TRUE)
{
pQueue- > pRearQueue = NULL ;
}
}
}
return pReturn;
}
QueueNode* peekLQ( LinkedQueue* pQueue)
{
//현재 pQueue의 FrontNode를 가져오는 함수
QueueNode* pReturn = NULL ;
if ( pQueue ! = NULL )
{
if ( isLinkedQueueEmpty( pQueue) == FALSE)
pReturn = pQueue- > pFrontQueue;
}
return pReturn;
}
void deleteLinkedQueue( LinkedQueue* pQueue)
{ //pQueue를 삭제하는 함수
QueueNode* pNode = NULL ;
QueueNode* pDelNode = NULL ;
while ( pQueue ! = NULL )
{
pNode = pQueue- > pFrontQueue;
while ( pNode ! = NULL )
{
pDelNode = pNode;
pNode = pNode- > pLink;
free ( pDelNode) ;
}
free ( pQueue) ;
}
}
int isLinkedQueueFull( LinkedQueue* pQueue)
{
int ret = FALSE;
return ret;
}
int isLinkedQueueEmpty( LinkedQueue* pQueue)
{
int ret = FALSE;
if ( pQueue ! = NULL )
{
if ( pQueue- > currentElementCount == 0 )
ret = TRUE;
}
return ret;
}
접기
main.cpp
더보기 접기
#include <stdio.h>
#include <stdlib.h>
#include "linkedqueue.h"
void displayLinkedQueue( LinkedQueue * pQueue)
{
QueueNode * pNode = NULL ;
int i = 0 ;
if ( pQueue ! = NULL ) {
printf ( "현재 노드 개수: %d\n " ,
pQueue- > currentElementCount) ;
pNode = pQueue- > pFrontQueue;
while ( pNode ! = NULL ) {
printf ( "[%d]-[%c]\n " , i, pNode- > data) ;
i++ ;
pNode = pNode- > pLink;
}
}
}
int enqueueLQChar( LinkedQueue* pQueue, char data)
{
QueueNode node = { 0 ,} ;
node.data = data;
return edqueueLQ( pQueue, node) ;
}
int main( int argc, char * argv[ ] )
{
LinkedQueue * pQueue = NULL ;
QueueNode * pNode = NULL ;
char value = 0 ;
// 배열 큐 생성
pQueue = createLinkedQueue( ) ;
if ( pQueue ! = NULL ) {
// 큐 초기화: 'A', 'B', 'C', 'D' 추가.
enqueueLQChar( pQueue, 'A' ) ;
enqueueLQChar( pQueue, 'B' ) ;
enqueueLQChar( pQueue, 'C' ) ;
enqueueLQChar( pQueue, 'D' ) ;
displayLinkedQueue( pQueue) ;
pNode = dequeueLQ( pQueue) ;
if ( pNode ! = NULL ) {
printf ( "Dequeue Value-[%c]\n " , pNode- > data) ;
free ( pNode ) ;
}
pNode = dequeueLQ( pQueue) ;
if ( pNode ! = NULL ) {
printf ( "Dequeue Value-[%c]\n " , pNode- > data) ;
free ( pNode ) ;
}
displayLinkedQueue( pQueue) ;
pNode = peekLQ( pQueue) ;
if ( pNode ! = NULL ) {
printf ( "Peek Value-[%c]\n " , pNode- > data) ;
}
displayLinkedQueue( pQueue) ;
// 큐에 'E', 'F' 추가.
enqueueLQChar( pQueue, 'E' ) ;
displayLinkedQueue( pQueue) ;
}
return 0 ;
}
접기
linkedqueue.cpp
linkedqueue.h
main.cpp