C#컬렉션과 LINQ

Queue와 Stack

Queue<T>(FIFO)와 Stack<T>(LIFO)의 내부 구조, Enqueue/Dequeue/Push/Pop/Peek 패턴, ConcurrentQueue와 PriorityQueue<T> 사용 기준을 정리합니다.

마지막 수정 2026년 3월 26일

기본 패턴

csharp
// Queue<T> — FIFO (선입선출)
var queue = new Queue<string>();
queue.Enqueue("첫 번째");
queue.Enqueue("두 번째");
string first = queue.Dequeue();   // "첫 번째"
string peek  = queue.Peek();      // "두 번째" (꺼내지 않음)

// Stack<T> — LIFO (후입선출)
var stack = new Stack<int>();
stack.Push(1);
stack.Push(2);
int top = stack.Pop();   // 2
int look = stack.Peek(); // 1

// 안전한 꺼내기
if (queue.TryDequeue(out string? item)) { /* ... */ }
if (stack.TryPop(out int value))        { /* ... */ }

설명

Queue<T> — FIFO 선입선출

Queue<T> 는 먼저 넣은 항목이 먼저 나오는 선입선출(FIFO) 자료구조입니다. 내부적으로 원형 배열로 구현되어 있어 앞뒤 추가/제거가 O(1)입니다.

csharp
var jobs = new Queue<string>();
jobs.Enqueue("작업A");
jobs.Enqueue("작업B");
jobs.Enqueue("작업C");

while (jobs.Count > 0)
{
    string job = jobs.Dequeue();  // A → B → C 순서
    Console.WriteLine($"처리: {job}");
}

실용 사례: 작업 대기열, 메시지 처리, 너비 우선 탐색(BFS), 프린터 스풀.

Stack<T> — LIFO 후입선출

Stack<T> 는 나중에 넣은 항목이 먼저 나오는 후입선출(LIFO) 자료구조입니다. 내부적으로 동적 배열로 구현되어 있습니다.

csharp
var history = new Stack<string>();
history.Push("페이지1");
history.Push("페이지2");
history.Push("페이지3");

// 뒤로 가기
string prev = history.Pop();  // "페이지3"
string curr = history.Peek(); // "페이지2"

실용 사례: 되돌리기(Undo), 괄호 유효성 검사, 깊이 우선 탐색(DFS), 호출 스택 구현.

ConcurrentQueue<T> — 멀티스레드 환경

ConcurrentQueue<T>lock 없이 스레드 안전한 큐입니다. 생산자-소비자 패턴에서 사용합니다.

csharp
var cq = new ConcurrentQueue<int>();

// 생산자 스레드
cq.Enqueue(1);

// 소비자 스레드 — TryDequeue 사용 (Dequeue 없음)
if (cq.TryDequeue(out int val))
{
    Console.WriteLine(val);
}

PriorityQueue<TElement, TPriority> (.NET 6+)

PriorityQueue 는 우선순위 숫자가 낮을수록 먼저 꺼냅니다. 내부적으로 최소 힙(min-heap) 으로 구현됩니다.

csharp
var pq = new PriorityQueue<string, int>();
pq.Enqueue("낮은 우선순위", 10);
pq.Enqueue("높은 우선순위", 1);
pq.Enqueue("중간 우선순위", 5);

string next = pq.Dequeue(); // "높은 우선순위" (priority=1)

빠른 정리

타입순서스레드 안전주요 메서드
Queue<T>FIFOEnqueue / Dequeue / Peek
Stack<T>LIFOPush / Pop / Peek
ConcurrentQueue<T>FIFOEnqueue / TryDequeue
PriorityQueue<T,P>우선순위 낮은 순Enqueue / Dequeue
상황선택
작업 대기열, BFSQueue<T>
Undo, DFSStack<T>
멀티스레드 작업 큐ConcurrentQueue<T>
중요도 순 처리PriorityQueue<T,P>

주의할 점

QueueStack에서 Dequeue/Pop을 호출하면 InvalidOperationException 이 발생합니다. 항상 Count > 0 확인 후 호출하거나 TryDequeue/TryPop 을 사용하세요.

PriorityQueue동일한 우선순위를 가진 요소 간의 순서를 보장하지 않습니다. 동일 우선순위 요소의 삽입 순서를 유지해야 한다면 우선순위를 튜플 (priority, insertOrder)로 조합해 사용하세요.

참고 링크

3 sources