[Data Structures | C++] Queue & Deque : 큐 & 데큐
큐(Queue) #
- 큐는 처음에 저장한 데이터를 가장 먼저 꺼내는 선입선출(FIFO:First In First Out) 구조로 되어 있다.
- 입출력이 양방향에서 이루어지는 데이터 구조이다.
- FRONT)는 가장 먼저 삽입된 자료의 기억공간을 가리키는 포인터이고 , REAR는 가장 마지막에 삽입된 자료가 위치한 기억장소를 가리키는 포인터이다.
- 데이터 입력은 FRONT 포인터를 통해서 하고, 데이터 삭제는 REAR 포인터를 통해서 한다.
- 삽입연산을 Enqueue 또는 Put, 삭제연산을 Dequeue 또는 Get라고 한다.
- 큐에서는 FRONT와 REAR가 같을 때 비어있는 공백큐 임을 알수 있다.
- overflow : 큐의 모든 기억장소가 꽉 채워져 있어서 더 이상 데이터를 삽입(Enqueue할 때)할 수 없다.
- underflow : 자료가 없다면 스택에는 삭제(Dequeue할 때)할 자료가 없다.
큐(Queue)의 연산 #
큐(Queue)는 FIFO(First-In-First-Out) 를 따른다.
- add(item) : item을 리스트의 끝부분에 추가한다.
- remove() : 리스트의 첫 번째 항목을 제거한다.
- peek() : 큐에서 가장 위에 있는 항목을 반환한다.
- isEmpty() : 큐가 비어 있을 때에 true를 반환한다.
큐(Queue)에서 처음과 마지막 노드를 갱신할 때 실수가 나오기 쉽다. {: .prompt-warning }
큐의 단점 #
- 데이터 삽입 후 계속 항목을 삭제하면 REAR와 FRONT가 만나게 되어 공백큐가 됨에도 불구하고 오버 플로우 현상이 발생한다. 즉, 메모리 낭비가 생기게 된다.
개선된 원형 큐가 나옴. #
- 원형 큐의 단점 : 메모리 공간은 잘 활용하나 배열로 구현되어 있기 때문에 큐의 크기가 제한되는 단점이 존재한다.
링크드 리스트로 큐가 나옴. #
- 링크드 리스트로 구현한 큐는 큐의 크기가 제한이 없고, 삽입, 삭제가 효과적이다.
큐의 용도 #
데이터가 입력된 시간 순서대로 처리해야 할 필요가 있는 상황에 이용한다.
- 너비 우선 탐색(BFS, Breadth-First Search) 구현
- 처리해야 할 노드의 리스트를 저장하는 용도로 큐(Queue)를 사용한다.
- 노드를 하나 처리할 때마다 해당 노드와 인접한 노드들을 큐에 다시 저장한다.
- 노드를 접근한 순서대로 처리할 수 있다.
- 캐시(Cache) 구현
- 우선순위가 같은 작업 예약 (인쇄 대기열)
- 선입선출이 필요한 대기열 (티켓 카운터)
- 콜센터 고객 대기시간
- 프린터의 출력 처리
- 윈도 시스템의 메시지 처리기
- 프로세스 관리
- 운영체제 작업 스케쥴링
- 컴퓨터 버퍼에서 주로 사용, 마구 입력이 되었으나 처리를 하지 못할 때, 버퍼(큐)를 만들어 대기 시킨다.
- 대기행렬 처리
- 인쇄작업 대기목록
- 큐는 데이터를 꺼낼 때 항상 첫 번째 저장된 데이터를 삭제하므로 배열리스트와 같은 배열 기반의 컬렉션 클래스를 사용한다면 데이터를 꺼낼 때마다 빈 공간을 채우기 위해서 데이터의 복사가 발생하므로 비효율적이다. 따라서 큐를 사용할때는 연결 리스트(Linked List)로 구현하는 것이 적합하다.
데큐(Double-Ended Queue) #
- 큐와 스택의 장점을 합쳐놓은 개념이다.
- 양쪽 끝에서 삽입과 삭제가 모두 가능한 자료구조이다.
- 두 개의 포인터를 사용하여, 양쪽에서 삽입과 삭제를 발생시킬 수 있다.
- 입력이 한쪽 끝으로만 가능하도록 설정한 데크인 입력제한데크(Scroll), 출력이 한쪽 끝으로만 가능하도록 설정한 데크인 출력제한데크(Shelf)가 있다.
C++로 구현한 큐 & 덱 (Queue & Deque) #
1class Queue
2{
3private:
4 DoubleList *doublelist;
5public:
6 Queue();
7 ~Queue();
8
9 DoubleList *getdouble() { return doublelist; }
10
11 void enqueue(int data, int position);
12 void dequeue(int position);
13 void display();
14};
15
16#include "Queue.h"
17
18Queue::Queue()
19{
20 doublelist = new DoubleList;
21}
22
23Queue::~Queue()
24{
25}
26
27void Queue::enqueue(int data, int _position) {
28 doublelist->insertNode(data, _position);
29}
30
31void Queue::dequeue(int position) {
32 doublelist->delNode(position);
33}
34
35void Queue::display() {
36 doublelist->displayNode();
37}
38
39//Manager.cpp
40void Manager::QueueRun() {
41 int menu = 0;
42 int _data = 0;
43
44 while (true)
45 {
46 cout << "1.삽입\n2.반환\n3.출력\n입력 : ";
47 cin >> menu;
48
49 switch (menu)
50 {
51 case INSERT:
52 cout << "추가 할 데이터 : ";
53 cin >> _data;
54 queue->enqueue(_data, -1);
55 queue->display();
56 break;
57 case DEL:
58 queue->dequeue(0);
59 queue->display();
60 break;
61 case COUT:
62 if (queue->getdouble()->getHead() == NULL) {
63 cout << "데이터가 없습니다." << endl << endl;
64 }
65 else {
66 queue->display();
67 }
68 break;
69 default:
70 break;
71 }
72 }
73}Advertisement