큐(Queue)는 한 쪽 끝에서 삽입이 일어나고, 그 반대쪽 끝에서 삭제가 일어나는 순차 리스트입니다. 새로운 원소가 삽입되는 끝을 Rear
라고 하고, 원소가 삭제되는 끝을 Front
라고 합니다. 먼저 삽입된 원소가 먼저 제거되는 선입선출(FIFO, First-In-Last-Out)의 특성을 가집니다.
Front
에 위치한 원소를 제거.Rear
에 새로운 원소를 삽입. 큐가 가득 찼을 경우, Delete
실행.true
를 반환함. 아닐 경우, false
를 반환함.true
를 반환함. 아닐 경우, false
를 반환함.#DEFINE ARRAY_SIZE N + 1 // 이 매크로 변수에 대해서는 '구현 과정에서 고려한 것' 참조
typedef struct IntQueue* IntQueueP;
typedef struct IntQueue {
int Elements[6];
int Rear, Front;
} IntQueue;
int Delete(IntQueueP Queue)
{
if (IsEmpty(Queue) == 1)
Error(1);
Queue->Front = (Queue->Front + 1) % ARRAY_SIZE;
return Queue->Elements[Queue->Front];
}
int Add(IntQueueP Queue, int Element)
{
if (IsFull(Queue) == 1)
Error(0);
Queue->Rear = (Queue->Rear + 1) % ARRAY_SIZE;
Queue->Elements[Queue->Rear] = Element;
return Element;
}
int IsEmpty(IntQueueP Queue)
{
if (Amount(Queue) == 0) return 1;
return 0;
}
int IsFull(IntQueueP Queue)
{
if (Amount(Queue) == ARRAY_SIZE - 1) return 1;
return 0;
}
IntQueueP Init()
{
IntQueueP Temp;
Temp = malloc(sizeof(IntQueue));
Temp->Front = 0;
Temp->Rear = 0;
return Temp;
}
void Error(int Code)
{
char* ErrCause[3] = { "큐가 꽉 참", "큐가 비어 있음", "기타 오류" };
printf("다음과 같은 오류가 발생하여 프로그램을 종료합니다: %s\n", ErrCause[Code]);
exit(-1);
}
int Amount(IntQueueP Queue)
{
if (Queue->Front == Queue->Rear) return 0;
else if (Queue->Front < Queue->Rear) return Queue->Rear - Queue->Front;
else return (SIZE - (abs(Queue->Rear - Queue->Front)));
}
이상의 코드는 원형 큐를 구현합니다. 원형 큐의 모습은 다음 그림과 같습니다:
큐가 꽉 차 있을 때 Front
와 Rear
의 위치는 다음 그림과 같습니다:
그림과 같이, 큐에 저장될 수 있는 원소가 최대 5개일 경우 배열에는 6칸의 공간이 필요합니다. 큐에 저장될 원소 5개에 Front
가 차지할 공간 1개가 더해지기 때문입니다. 일반화하면, 큐의 최대 크기가 N일 때 배열의 크기는 N + 1이 되어야 합니다.
따라서, 매크로 변수 ARRAY_SIZE는 배열의 크기와 같이 N + 1로 설정합니다. 그리고 이를 고려하면 다음과 같은 관계가 성립합니다:
ARRAY_SIZE
= 큐의 최대 크기 + 1
원형 큐의 특징을 다시 한 번 생각해보며 그림을 봅시다:
현재 큐의 Rear
가 큐의 최대 크기인 5와 일치합니다. 만약 이 상태에서 원소를 삽입한다면,다음 Rear
는 그림과 같이 0이 됩니다. 이를 수식화하면 다음과 같습니다:
Rear
= (Rear
+ 1) %ARRAY_SIZE
- 현재 Rear = 1일 경우, 다음 Rear = (1 + 1) % 6 = 2
- 현재 Rear = 2일 경우, 다음 Rear = (2 + 1) % 6 = 3
...- 현재 Rear = 5일 경우, 다음 Rear = (5 + 1) % 6 = 0
이상의 수식은 큐에 원소를 추가할 때의 Rear
뿐만 아니라, 큐에서 원소를 제거할 때의 Front
에도 동일하게 적용할 수 있습니다.
가능한 경우의 수는 3가지입니다:
Front
==Rear
일 때, 0.Front
<Rear
일 때,Rear
-Front
.Front
>Rear
일 때,ARRAY_SIZE
- (|Front
-Rear
|).
1은 큐가 비어 있는 상태를 의미합니다. 이 경우 저장된 원소의 개수는 0입니다.
2와 3은 큐가 채워져 있는 상태를 의미하지만, 모양이 조금 다릅니다.
2는 다음과 같은 모양을 갖습니다:이 경우 저장된 원소의 개수는 단순하게 Rear
- Front
입니다.
3은 다음과 같은 모양을 갖습니다:
이 경우 저장된 원소의 개수는 ARRAY_SIZE
- (|Front
- Rear
|)입니다.