일상생활에서 큐 구조를 쉽게 찾을 수 있습니다.
기차가 터널에 들어가는 순서대로 터널을 빠져나옵니다.
먼저 줄을 선 사람이 먼저 서비스를 받습니다.
먼저 온 순서대로 표를 구매합니다.
먼저 넣은 것이 먼저 나오는 FIFO(First In First Out) 구조가 바로 "큐"입니다! 스택(LIFO)과 반대 개념입니다.
Queue structures can be easily found in everyday life.
The train exits the tunnel in the same order it entered.
The first person in line gets served first.
Tickets are sold in the order people arrived.
A FIFO (First In First Out) structure where the first item added is the first removed is called a "Queue"! It's the opposite of a Stack (LIFO).
| 구분 | 스택 (Stack) | 큐 (Queue) |
|---|---|---|
| 원리 | LIFO (후입선출) | FIFO (선입선출) |
| 삽입 | push | enQueue |
| 추출 | pop | deQueue |
| 확인 | peek (top) | peek (front+1) |
| 입/출구 | 같은 쪽 (top) | 다른 쪽 (rear/front) |
| 비유 | 종이컵 수거함 | ATM 대기줄 |
스택은 입구 = 출구 (한쪽만), 큐는 입구 ≠ 출구 (양쪽이 다름)!
| Category | Stack | Queue |
|---|---|---|
| Principle | LIFO (Last In First Out) | FIFO (First In First Out) |
| Insert | push | enQueue |
| Remove | pop | deQueue |
| Peek | peek (top) | peek (front+1) |
| In/Out | Same end (top) | Different ends (rear/front) |
| Analogy | Cup collector | ATM waiting line |
Stack has entrance = exit (one end), Queue has entrance ≠ exit (two different ends)!
큐에 데이터를 삽입하는 작동. rear(꼬리) 쪽에서 데이터가 들어옵니다.
큐에서 데이터를 추출하는 작동. front(머리) 쪽에서 데이터가 나갑니다.
저장된 데이터 중 가장 먼저 들어온 데이터의 바로 앞 위치. 초기값은 -1입니다.
저장된 데이터 중 가장 마지막에 들어온 데이터의 위치. 초기값은 -1입니다.
다음에 추출될 데이터를 큐에서 꺼내지 않고 확인만 합니다. front+1 위치의 데이터입니다.
front는 실제 데이터 위치가 아닌, 가장 앞 데이터의 바로 앞 칸을 가리킵니다. 따라서 실제 첫 번째 데이터는 queue[front+1]에 있습니다.
The operation of inserting data into the queue. Data enters from the rear (tail) side.
The operation of removing data from the queue. Data exits from the front (head) side.
The position just before the earliest inserted data. Initial value is -1.
The position of the most recently inserted data. Initial value is -1.
View the next data to be removed without actually removing it. It is at position front+1.
front does NOT point to actual data — it points to the position just before the first data. So the actual first element is at queue[front+1].
배열 크기를 지정하여 빈 큐를 생성하고, rear를 증가시키며 데이터를 삽입합니다.
Create an empty queue with a fixed size, then insert data by incrementing rear.
front를 증가시키고 해당 위치의 데이터를 꺼낸 후 None으로 비웁니다.
Increment front, extract data at that position, then set it to None.
크기 5인 빈 큐를 만들고, "정국", "뷔", "지민" 세 명을 차례로 enQueue한 뒤 큐의 상태와 front, rear 값을 출력하시오. 그리고 한 명을 deQueue하여 누가 나왔는지 출력하시오.
큐 상태: ['정국', '뷔', '지민', None, None] front: -1 , rear: 2 deQueue --> 정국 큐 상태: [None, '뷔', '지민', None, None] front: 0 , rear: 2
큐에 "A", "B", "C", "D"를 삽입한 후 2개를 추출하고, 다시 "E"를 삽입하세요. 각 단계마다 큐 상태, front, rear 값을 출력하시오.
삽입 후: ['A', 'B', 'C', 'D', None] front: -1 rear: 3 deQueue: A deQueue: B 추출 후: [None, None, 'C', 'D', None] front: 1 rear: 3 삽입 후: [None, None, 'C', 'D', 'E'] front: 1 rear: 4
Create an empty queue of size 5, enQueue "정국", "뷔", "지민" in order, then print the queue state and front/rear values. Then deQueue one person and print who came out.
Insert "A", "B", "C", "D" into the queue, extract 2, then insert "E". Print the queue state, front, and rear at each step.
rear 값이 SIZE-1과 같으면 큐가 꽉 찬 상태입니다.
큐가 꽉 차지 않았으면 rear를 1 증가시키고 데이터를 삽입합니다.
If rear equals SIZE-1, the queue is full.
If the queue is not full, increment rear by 1 and insert data.
The queue is full when rear == SIZE - 1, meaning the last index of the array has been reached.
front와 rear 값이 같으면 큐가 비어있는 상태입니다.
If front equals rear, the queue is empty.
Stack peek returns stack[top], but Queue peek returns queue[front+1] because front is one position before the first data.
앞쪽에 빈 공간이 있어도 rear가 끝에 도달하면 "꽉 찼다"고 판단합니다.
rear가 끝에 도달했지만 앞에 빈 칸이 있으면, 데이터를 왼쪽으로 이동시킵니다.
Even with empty spaces at the front, when rear reaches the end, it reports "full".
After several deQueue operations, the front slots are empty. But since rear == SIZE-1, isQueueFull() returns True, wasting space!
When rear hits the end but front slots are empty, shift all data left.
Shifting data works but takes O(n) time. For large queues (e.g., 100,000 elements), this causes significant overhead. The solution? Circular Queue (Part 3)!
유명 맛집의 대기줄을 큐로 구현하시오. 5명이 차례로 줄을 서고, 한 명씩 식당에 들어갑니다. deQueue 할 때 나머지 사람들을 앞으로 이동시키시오.
개선된 isQueueFull() 함수(데이터 이동 방식)를 포함한 완전한 큐를 작성하고, 사용자 입력으로 삽입/추출/확인/종료 메뉴를 구현하시오.
Implement a restaurant waiting line using a queue. 5 people line up in order, and each enters the restaurant one by one. When deQueuing, shift remaining people forward.
Write a complete queue with the improved isQueueFull() (data shifting), and implement an interactive menu for Insert/Extract/View/Exit.
See the Korean column for the complete source code (Code07-10). The key improvement is the 3-case isQueueFull() that shifts data left when rear hits the end but front slots are empty.
크기 10만인 큐에서 앞쪽 일부만 비어 있고 나머지가 꽉 찬 경우, 데이터 이동에 엄청난 시간(오버헤드)이 발생합니다.
순차 큐를 구부려서 끝을 이으면 원형 큐가 됩니다. 데이터 이동 없이 front와 rear가 순환합니다.
In a queue of size 100,000 where only a few front slots are empty, shifting all data causes enormous overhead.
By bending the sequential queue into a ring, front and rear wrap around — no data movement needed.
Instead of rear += 1, we use:
rear = (rear + 1) % SIZE
This makes the index wrap around: after the last slot, it goes back to 0.
Sequential queue: front = rear = -1
Circular queue: front = rear = 0
No data shifting needed! O(1) for both enQueue and deQueue. The circular structure reuses empty front slots automatically.
초기값 front=0, rear=0에서 시작합니다. front와 rear가 같으면 큐가 비어있습니다.
rear의 다음 칸이 front와 같으면 큐가 꽉 찬 것입니다. 이 때문에 원형 큐는 한 칸을 비워둡니다.
크기 5인 원형 큐에는 최대 4개의 데이터만 저장할 수 있습니다. 한 칸을 비워서 "꽉 참"과 "비어 있음"을 구분합니다.
Starting from front=0, rear=0. When front and rear are equal, the queue is empty.
When rear's next position equals front, the queue is full. That's why a circular queue always leaves one slot empty.
A circular queue of size 5 can only store 4 items max. The empty slot distinguishes "full" from "empty".
모든 인덱스 계산에 % SIZE를 사용하여 배열 끝을 넘어가면 자동으로 처음으로 돌아옵니다!
(4 + 1) % 5 = 0 → wraps to start!
(2 + 1) % 5 = 3 → normal increment
(3 + 1) % 5 = 4 → normal increment
Notice: front = rear = 0 (not -1), and all index operations use % SIZE.
각 전화에 (유형, 소요시간) 튜플을 사용하여 원형 큐로 대기 시간을 계산합니다.
대기 예상시간: 0 분
현재 대기 콜 --> [None, None, None, None, None, None]
대기 예상시간: 9 분
현재 대기 콜 --> [None, ('사용', 9), None, None, None, None]
대기 예상시간: 12 분
...
최종 대기 콜 --> [None, ('사용', 9), ('고장', 3), ('환불', 4), ('환불', 4), ('고장', 3)]
Each call is a tuple (type, duration). Use a circular queue to calculate waiting time.
This is exactly how real call centers work! New calls enQueue at the back, and the operator deQueues from the front. The wait time is the sum of all preceding call durations.
| 구분 | 순차 큐 | 원형 큐 |
|---|---|---|
| 초기값 | front=rear=-1 | front=rear=0 |
| 꽉 참 조건 | rear == SIZE-1 | (rear+1)%SIZE == front |
| 비어 있음 | front == rear | front == rear |
| 삽입 방식 | rear += 1 | rear = (rear+1)%SIZE |
| 추출 방식 | front += 1 | front = (front+1)%SIZE |
| 공간 재활용 | 데이터 이동 필요 | 자동 순환 |
| 최대 저장 | SIZE개 | SIZE-1개 |
| 시간 복잡도 | 이동 시 O(n) | 항상 O(1) |
실무에서는 대부분 원형 큐를 사용합니다. 데이터 이동 오버헤드가 없고 효율적이기 때문입니다!
| Category | Sequential Queue | Circular Queue |
|---|---|---|
| Initial | front=rear=-1 | front=rear=0 |
| Full | rear == SIZE-1 | (rear+1)%SIZE == front |
| Empty | front == rear | front == rear |
| Insert | rear += 1 | rear = (rear+1)%SIZE |
| Remove | front += 1 | front = (front+1)%SIZE |
| Space Reuse | Requires shifting | Auto circular |
| Max Storage | SIZE items | SIZE-1 items |
| Time | O(n) for shift | Always O(1) |
In practice, Circular Queues are preferred because they have no data shifting overhead and are always O(1)!
원형 큐를 구현하고, 삽입/추출/확인/종료 메뉴를 통해 사용자가 직접 큐를 조작할 수 있게 하시오. 매 조작마다 큐 상태와 front, rear 값을 출력하시오.
원형 큐를 이용하여 콜센터 대기 시간을 계산하시오. 5개의 전화가 ('사용',9), ('고장',3), ('환불',4), ('환불',4), ('고장',3) 순서로 들어올 때, 각 전화마다 현재 대기 시간을 출력하시오.
Implement a circular queue with an Insert/Extract/View/Exit menu. Print the queue state, front, and rear after each operation.
See the Korean column for the complete source code (Code07-11). Key points: front = rear = 0, all index operations use % SIZE.
Using a circular queue, calculate call center wait times. 5 calls arrive: ('Usage',9), ('Broken',3), ('Refund',4), ('Refund',4), ('Broken',3). Print the current wait time for each call.
Expected wait: 0 min Expected wait: 9 min Expected wait: 12 min Expected wait: 16 min Expected wait: 20 min