큐 (Queue)의 개념 및 구현
2024. 11. 4. 16:25ㆍData Structure
큐(Queue)는 FIFO(First In, First Out) 방식으로 동작하는 대표적인 자료구조입니다.
먼저 들어온 데이터가 먼저 처리되며, 일상생활의 줄 서기와 비슷한 개념입니다.
이번 포스팅에서는 큐의 기본 개념과 특징, 주요 연산, 그리고 C#을 활용한 구현 방법을 자세히 살펴보겠습니다.
1. 큐 (Queue)란?
큐는 데이터를 저장하고 관리하는 선형 자료구조로, 가장 먼저 추가된 데이터가 가장 먼저 삭제됩니다.
데이터를 넣는 쪽은 후단(Rear) 또는 enqueue라고 하고, 데이터를 꺼내는 쪽은 전단(Front) 또는 dequeue라고 합니다.
큐의 구조
- Enqueue: 큐의 끝에 데이터를 추가하는 연산
- Dequeue: 큐의 앞에서 데이터를 제거하는 연산
- Peek: 현재 큐의 첫 번째 요소를 반환하되, 제거하지 않는 연산
큐는 FIFO 방식이기 때문에 먼저 들어온 데이터부터 차례로 처리되며, 배치나 요청 관리에서 자주 사용됩니다.
2. 큐의 주요 연산
큐에서 제공되는 주요 연산은 다음과 같습니다.
- Enqueue: 큐의 끝에 새 요소를 추가합니다.
- Dequeue: 큐의 앞에서 요소를 제거합니다. 큐가 비어있으면 제거할 수 없습니다.
- Peek: 큐의 앞에 있는 요소를 반환하지만 큐에서 제거하지 않습니다.
- IsEmpty: 큐가 비어 있는지 확인합니다.
- IsFull (고정 크기 큐의 경우): 큐가 가득 찼는지 확인합니다.
3. 큐의 활용 사례
큐는 데이터가 들어온 순서대로 처리되어야 하는 상황에서 유용합니다.
- 프로세스 관리: 운영체제에서 프로세스를 일정 순서에 따라 실행하는 데 사용됩니다.
- 프린터 대기열: 문서가 요청된 순서대로 출력됩니다.
- 네트워크 패킷 처리: 패킷이 수신된 순서대로 처리됩니다.
4. 큐의 구현 - C# 코드 예제
큐를 C#에서 직접 구현할 수 있으며, List나 Queue<T> 클래스도 큐로 활용 가능합니다.
여기에서는 배열을 이용하여 기본 큐를 구현해보겠습니다.
4.1 큐 클래스 구현
배열 기반 큐에서는 front와 rear를 이용해 데이터의 출입을 관리합니다.
public class Queue
{
private int[] elements;
private int front;
private int rear;
private int maxSize;
private int count;
// 큐 생성자
public Queue(int size)
{
maxSize = size;
elements = new int[maxSize];
front = 0;
rear = -1;
count = 0;
}
// Enqueue - 큐에 요소 추가
public void Enqueue(int data)
{
if (IsFull())
{
Console.WriteLine("Queue is full.");
return;
}
rear = (rear + 1) % maxSize;
elements[rear] = data;
count++;
}
// Dequeue - 큐에서 요소 제거
public int Dequeue()
{
if (IsEmpty())
{
Console.WriteLine("Queue is empty.");
throw new InvalidOperationException("Queue is empty.");
}
int data = elements[front];
front = (front + 1) % maxSize;
count--;
return data;
}
// Peek - 큐의 앞쪽 요소 반환 (제거하지 않음)
public int Peek()
{
if (IsEmpty())
{
Console.WriteLine("Queue is empty.");
throw new InvalidOperationException("Queue is empty.");
}
return elements[front];
}
// 큐가 비었는지 확인
public bool IsEmpty()
{
return count == 0;
}
// 큐가 가득 찼는지 확인
public bool IsFull()
{
return count == maxSize;
}
}
4.2 큐의 사용 예시
위에서 구현한 큐 클래스를 사용하여 데이터를 추가하고 제거하는 예제입니다.
public class Program
{
public static void Main()
{
Queue queue = new Queue(5);
queue.Enqueue(1);
queue.Enqueue(2);
queue.Enqueue(3);
Console.WriteLine("Peek: " + queue.Peek()); // 1 출력
Console.WriteLine("Dequeue: " + queue.Dequeue()); // 1 제거
Console.WriteLine("Dequeue: " + queue.Dequeue()); // 2 제거
queue.Enqueue(4);
queue.Enqueue(5);
while (!queue.IsEmpty())
{
Console.WriteLine("Dequeue: " + queue.Dequeue());
}
}
}
코드 설명
- Enqueue: 큐의 끝에 요소를 추가합니다. rear가 순환형으로 이동하도록 설정해 배열을 재활용할 수 있습니다.
- Dequeue: 큐의 앞에서 요소를 제거합니다. front가 다음 위치로 이동하도록 설정합니다.
- Peek: 현재 front가 가리키는 요소를 반환하지만 제거하지 않습니다.
- IsEmpty, IsFull: 현재 큐 상태를 확인합니다.
5. 큐의 장점과 단점
장점
- 간단한 데이터 관리: FIFO 방식으로 데이터의 순서가 명확하게 유지됩니다.
- 효율적인 삽입/삭제: 데이터의 끝에서 삽입, 시작에서 삭제하는 구조로 효율적입니다.
단점
- 고정 크기 큐의 제한: 배열 기반 큐는 배열의 크기를 미리 지정해야 하므로 유연성이 떨어질 수 있습니다.
- 원형 큐(Circular Queue) 필요: 배열을 재사용하려면 원형 큐 개념이 필요합니다.
큐는 데이터가 입력된 순서대로 처리해야 하는 경우 유용한 자료구조입니다.
운영체제의 프로세스 스케줄링, 네트워크 패킷 관리 등 실생활에서 빈번히 사용되는 큐의 개념과 기본적인 구현을 알아보았습니다.
'Data Structure' 카테고리의 다른 글
이진 트리 (Binary Tree)의 개념 및 구현 (1) | 2024.11.11 |
---|---|
우선순위 큐 (Priority Queue)의 개념 및 구현 (0) | 2024.11.08 |
이중 연결 리스트 (Doubly Linked List)의 개념 및 구현 (0) | 2024.11.03 |
단일 연결 리스트 (Singly Linked List)의 개념 및 구현 (0) | 2024.11.03 |
배열 (Array)의 개념 및 구현 (0) | 2024.10.27 |