큐 (자료 구조)
"오늘의AI위키"의 AI를 통해 더욱 풍부하고 폭넓은 지식 경험을 누리세요.
1. 개요
큐는 데이터를 넣는 enqueue 연산과 데이터를 꺼내는 dequeue 연산을 통해 구현되는 자료 구조이다. 큐는 선형 큐와 환형 큐로 나뉘며, 선형 큐는 데이터가 일렬로 저장되는 반면, 환형 큐는 큐의 끝에 도달하면 다시 처음으로 연결되는 원형 구조를 가진다. 큐는 배열 또는 연결 리스트를 기반으로 구현할 수 있으며, 우선순위 큐, 메시지 큐, 명령 큐, 태스크 큐, 버퍼 등 다양한 분야에 응용된다. 또한 큐 머신과 같은 계산 모델에서도 사용되며, 여러 프로그래밍 언어에서 큐를 지원한다.
더 읽어볼만한 페이지
- 추상 자료형 - 리스트 (컴퓨팅)
리스트는 컴퓨터 과학에서 항목들을 순서대로 저장하고 관리하는 기본적인 자료 구조이며, 다양한 연산을 지원하고 연결 리스트나 동적 배열 등으로 구현되며 큐, 스택 등 다른 자료형의 기반이 된다. - 추상 자료형 - 스택
스택은 후입선출(LIFO) 원칙에 따라 데이터를 관리하는 추상 자료형으로, push 연산으로 데이터를 쌓고 pop 연산으로 가장 최근 데이터를 제거하며, 서브루틴 호출 관리, 수식 평가, 백트래킹 등에 활용된다. - 자료 구조 - 라우팅 테이블
라우팅 테이블은 네트워크에서 데이터 전송 시 최적 경로를 결정하는 핵심 데이터베이스로, 라우터가 목적지 IP 주소를 기반으로 다음 홉을 결정하며 직접 연결 및 원격 네트워크 경로 정보를 저장하고 동적 라우팅 또는 수동 설정으로 관리된다. - 자료 구조 - 스택
스택은 후입선출(LIFO) 원칙에 따라 데이터를 관리하는 추상 자료형으로, push 연산으로 데이터를 쌓고 pop 연산으로 가장 최근 데이터를 제거하며, 서브루틴 호출 관리, 수식 평가, 백트래킹 등에 활용된다.
큐 (자료 구조) |
---|
2. 용어
큐는 데이터를 넣는 `put` (또는 `enqueue`) 연산과 데이터를 꺼내는 `get` (또는 `dequeue`) 연산을 통해 구현된다.[1] `front` (또는 `head`)는 데이터를 꺼낼 수 있는 위치를, `rear` (또는 `tail`)는 데이터를 넣을 수 있는 위치를 가리킨다.[1] 큐가 꽉 차서 더 이상 데이터를 넣을 수 없는 경우를 오버플로우, 큐가 비어 있어 데이터를 꺼낼 수 없는 경우를 언더플로우라고 한다.[1]
큐에는 선형과 환형이 있다.[1] 이론적으로 큐는 특정 용량이 정해져 있지 않아, 이미 포함된 요소의 수에 관계없이 항상 새 요소를 추가할 수 있다. 또한, 큐가 비어 있을 수도 있는데, 이 경우에는 새 요소를 다시 추가하기 전까지는 요소를 제거할 수 없다.
3. 종류
배열을 닫힌 원 형태로 만들고, 머리(head)와 꼬리(tail)가 그 원 안에서 끊임없이 이동하도록 하는 방식으로 큐를 구현할 수 있다. 이 방법은 고급 프로그래밍 언어에서 큐를 구성하는 개념적으로 가장 간단한 방법 중 하나이다. 제한된 큐는 고정된 수의 항목으로 제한된 큐이다.[1]
FIFO 큐를 효율적으로 구현하는 방법에는 여러 가지가 있다. 효율적인 구현은 큐에 요소를 추가(en-queue)하거나 제거(de-queue)하는 작업을 O(1) 시간에 수행할 수 있는 구현이다.3. 1. 선형 큐 (Linear Queue)
선형 큐는 막대 모양으로, 데이터가 일렬로 저장되는 큐이다. 구현이 간단하지만, 크기가 제한되어 있고, 삭제 연산 후 빈 공간을 활용하기 위해서는 데이터를 이동시켜야 하는 단점이 있다.
선형 큐의 작동 방식은 다음과 같다.
DATA : A B C D E
{| class="wikitable" style="text-align:center;"
|+ 선형 큐의 작동 방식 예시
|-
! style="width:150px;" | ENQ(A) !! style="width:150px;" | ENQ(B) !! style="width:150px;" | ENQ(C) !! style="width:150px;" | DEQ(A) !! style="width:150px;" | ENQ(D) !! style="width:150px;" | DEQ(B)
|-
| style="vertical-align:middle;" |
A |
| style="vertical-align:middle;" |
B |
A |
| style="vertical-align:middle;" |
C |
B |
A |
| style="vertical-align:middle;" |
C |
B |
| style="vertical-align:middle;" |
D |
C |
B |
| style="vertical-align:middle;" |
D |
C |
|}
3. 2. 환형 큐 (Circular Queue)
큐에는 선형과 환형이 있다. 선형 큐의 문제점(배열로 큐를 선언할 시 큐의 삭제와 생성이 계속 일어났을 때, 마지막 배열에 도달 후 실제로는 데이터 공간이 남아있지만 오버플로우가 발생)을 보완한 것이 환형 큐이다. front가 큐의 끝에 닿으면 큐의 맨 앞으로 자료를 보내어 원형으로 연결하는 방식이다.[1]원형 큐라고도 한다.
환형 큐의 작동 방식은 다음과 같다(A, B, C, D, E는 데이터).
{| class="wikitable" style="text-align:center;"
|+ 자료 삽입/삭제 과정
|-
! 과정 !! 내용
|-
| 1 || ENQ(A)
|-
| colspan="2" |
A |
|-
| 2 || ENQ(B)
|-
| colspan="2" |
B |
A |
|-
| 3 || ENQ(C)
|-
| colspan="2" |
C |
B |
A |
|-
| 4 || ENQ(D)
|-
| colspan="2" |
D |
C |
B |
A |
|-
| 5 || DEQ(A)
|-
| colspan="2" |
D |
C |
B |
|-
| 6 || ENQ(E)
|-
| colspan="2" |
D |
C |
B |
E |
|}
4. 구현
큐는 데크의 특수한 경우로 간주되어 별도로 구현되지 않거나, 자료형으로 구현될 수 있다. 예를 들어, Perl과 Ruby에서는 배열의 양쪽 끝에서 요소를 추가하고 제거하는 기능을 제공하여, `push`와 `shift` 함수 (또는 `unshift`와 `pop`)를 통해 큐처럼 사용할 수 있다.[2]
C++의 표준 템플릿 라이브러리는 `queue` 템플릿 클래스를 제공하며, 이는 푸시/팝 연산만 허용한다. Java 라이브러리는 `Queue` 인터페이스를 포함하며, `LinkedList`와 `ArrayDeque` 등의 구현 클래스를 제공한다. PHP에는 `SplQueue` 클래스와 함께 beanstalk'd, Gearman과 같은 외부 라이브러리를 활용할 수 있다.
다음은 자바스크립트로 구현된 간단한 큐이다:
```javascript
class Queue {
constructor() {
this.items = [];
}
enqueue(element) {
this.items.push(element);
}
dequeue() {
return this.items.shift();
}
}
4. 1. 배열 기반 구현
고정 길이 배열을 사용하여 큐를 구현할 수 있다.[1] 배열을 닫힌 원처럼 만들고 헤드와 테일이 그 원 안에서 끊임없이 순환하도록 하면, 배열에 저장된 항목을 이동할 필요 없이 큐를 효율적으로 사용할 수 있다. 배열의 크기가 n일 때, 인덱스를 n으로 나눈 나머지 연산을 사용하면 배열이 원형이 된다. 이는 개념적으로 큐를 구현하는 간단한 방법이지만, 배열 인덱스 범위를 확인해야 하므로 속도가 약간 느려질 수 있다.배열 크기는 사전에 선언되어야 하지만, 일부 구현에서는 큐가 가득 차서 오버플로가 발생하면 배열 크기를 두 배로 늘리기도 한다. 객체나 포인터를 사용하는 최신 프로그래밍 언어들은 동적 목록을 구현하거나 관련 라이브러리를 제공하여, 메모리 제약 외에는 용량 제한이 없을 수 있다. 큐 ''오버플로''는 가득 찬 큐에 요소를 추가하려고 할 때 발생하며, 큐 ''언더플로''는 빈 큐에서 요소를 제거하려고 할 때 발생한다.
4. 2. 연결 리스트 기반 구현 (Linked Queue)
연결 리스트로 구현한 큐는 연결 리스트를 사용하여 큐의 길이를 쉽게 늘릴 수 있으므로 오버플로우가 발생하지 않는다. 필요에 따라 환형으로 만들 수도 있다.[1] 삽입과 삭제 연산은 O(1) 시간에 수행할 수 있다.- 연결 리스트
- 이중 연결 리스트는 양쪽 끝에서 O(1) 삽입 및 삭제가 가능하므로 큐 구현에 적합하다.
- 일반 단일 연결 리스트는 한쪽 끝에서만 효율적인 삽입 및 삭제가 가능하다. 그러나 첫 번째 노드뿐만 아니라 ''마지막'' 노드를 가리키는 포인터를 추가하면 효율적인 큐를 구현할 수 있다.
5. 우선순위 큐 (Priority Queue)
우선순위 큐는 큐에 추가하는 요소에 우선순위를 부여하고, 우선순위에 따라 큐 내에서 정렬하는 것이다. 속도 향상을 위한 다양한 알고리즘이 연구되고 있으며, 또한 여러 다른 알고리즘에서 간접적으로 사용된다.
6. 큐의 응용
- 메시지 큐: 컴퓨터 시스템 내에서 프로세스 간 통신(IPC)에 사용되는 메시지를 저장하는 큐이다.[1]
- UNIX에서는 `msgsnd` 및
msgrcv
시스템 콜을 통해 데이터를 송수신할 수 있다. 데이터를 전송하는 대상은 동일한 프로세스일 수도 있고, 다른 프로세스일 수도 있다. - Microsoft Windows에서는 이벤트 루프를 가진 스레드 또는 프로세스에 이벤트를 전송하는 데 사용되어, 이벤트 구동 프로그래밍을 실현한다. 특히 GUI 애플리케이션에서 필수적이며, 프로그램은 수신한 이벤트 메시지를 하나씩 메시지 루프 내에서 가져와서 적절한 프로시저(이벤트 핸들러)에 배포하고, 이벤트에 대응하는 동작을 실행한다. 메시지 정보는
MSG
구조체에 의한 인터페이스를 통해 제공된다. - 명령 큐: 소프트웨어나 하드웨어에 여러 명령을 전송하여 비동기적으로 실행하기 위한 큐이다.[1]
- 예를 들어 그래픽 하드웨어 (GPU)와의 양방향 통신에는 시간이 걸리므로, 처리량을 향상시키기 위해 대부분의 그리기 명령은 응답이 필요 없는 단방향 형식이 되어, 일단 명령 큐에 큐잉되어, 일괄적으로 비동기적으로 배치 처리된다.
- 명령 큐는 하드웨어에 가까운 장치 드라이버 계층에서 구현되어 있으며, 상위 레벨의 API나 미들웨어를 이용하는 애플리케이션 계층에서는 의식하지 않아도 될 때도 있지만, 하위 레벨의 API에서는 미들웨어나 애플리케이션 측에서 명시적으로 명령 큐를 이용하기도 한다.
- 태스크 큐: 워커 스레드 또는 서비스 프로세스에 위임하는 처리를 일시적으로 저장해두기 위한 큐이다.[1]
7. 큐 머신 (Queue Machine)
큐 머신은 중간 결과를 저장하기 위해 큐를 사용하는 계산 모델이다.
연산은 큐에 저장된 데이터를 사용하여 수행되며, 결과는 다시 큐에 저장된다. 따라서 스택 머신과 마찬가지로 0-주소 명령어 형식을 사용할 수 있다.
또한, 큐 머신은 데이터 흐름에 따라 명령을 실행하는 특징을 가진다.
8. 프로그래밍 언어 지원
다양한 프로그래밍 언어에서 큐 자료 구조를 지원하거나 큐와 유사한 기능을 제공한다.
- C++의 표준 템플릿 라이브러리는 "queue" 템플릿 클래스를 제공하며, 이 클래스는 푸시(push) 및 팝(pop) 연산으로 제한된다.
- Java의 라이브러리(J2SE5.0부터)는 큐 연산을 지정하는 인터페이스를 포함한다. 구현 클래스에는 LinkedList와 (J2SE 1.6부터) ArrayDeque가 있다.
- PHP에는 [http://www.php.net/manual/en/class.splqueue.php SplQueue] 클래스가 있으며, beanstalk'd 및 Gearman과 같은 타사 라이브러리도 있다.
- Perl과 Ruby는 배열의 양쪽 끝에서 푸시와 팝을 허용하므로, '''push'''와 '''shift''' 함수를 사용하여 목록을 큐에 넣고 빼낼 수 있다(또는 반대로 '''unshift'''와 '''pop'''을 사용할 수 있다).[2]
순수 함수형 프로그래밍 언어에서도 큐를 구현할 수 있다.[3] 두 가지 구현 방법이 있는데, 하나는 연산당 평균 상각 분석 O(1) 시간이 걸리지만 개별 연산은 큐의 요소 수에 따라 O(n) 시간이 걸릴 수 있다. 다른 하나는 '''실시간 큐'''[4]라고 불리며, O(1) 최악의 경우 시간 복잡도로 연산을 수행하면서 큐가 불변 자료 구조가 되도록 한다.
참조
[1]
웹사이트
Queue (Java Platform SE 7)
http://docs.oracle.c[...]
Docs.oracle.com
2014-05-22
[2]
웹사이트
Array (Ruby 3.1)
https://ruby-doc.org[...]
2022-05-11
[3]
웹사이트
Purely Functional Data Structures
https://doc.lagout.o[...]
[4]
논문
Real-time queue operations in pure Lisp
1981-11
[5]
문서
FIFO
[6]
문서
enqueue
[7]
문서
dequeue
[8]
문서
double-ended queue
[9]
문서
LIFO
[10]
Microsoft Docs
MSG (winuser.h) - Win32 apps
https://docs.microso[...]
[11]
Microsoft Docs
Design Philosophy of Command Queues and Command Lists - Win32 apps
https://docs.microso[...]
[12]
Microsoft Docs
Queue サービスを作成する
https://docs.microso[...]
본 사이트는 AI가 위키백과와 뉴스 기사,정부 간행물,학술 논문등을 바탕으로 정보를 가공하여 제공하는 백과사전형 서비스입니다.
모든 문서는 AI에 의해 자동 생성되며, CC BY-SA 4.0 라이선스에 따라 이용할 수 있습니다.
하지만, 위키백과나 뉴스 기사 자체에 오류, 부정확한 정보, 또는 가짜 뉴스가 포함될 수 있으며, AI는 이러한 내용을 완벽하게 걸러내지 못할 수 있습니다.
따라서 제공되는 정보에 일부 오류나 편향이 있을 수 있으므로, 중요한 정보는 반드시 다른 출처를 통해 교차 검증하시기 바랍니다.
문의하기 : help@durumis.com