티스토리 뷰
이 글은 순환 큐(Circular Queue)에 대해 다루겠습니다. 전체적인 내용은 Programiz를 정리했습니다. 공부한 것을 정리하는 형식으로 작성되었으므로 오류가 있을 수 있습니다. 오류 발견시 댓글로 꼭 말씀해주세요! 시작해볼까요?
'순환 큐'하면 제일 먼저 떠오르는 중요한 개념은 일반 큐 또는 배열보다 공간을 효율적으로 사용한다는 점입니다.
아래 [그림1]에 총 11번의 enqueue와 7번의 dequeue가 일어난 큐를 표현 해 놓았습니다. 앞으로 새로운 값을 이 큐에 넣을 때는 뒤로 넣게 되기 때문에 앞에 dequeue된 공간은 사용하지 못합니다.(물론 큐를 empty시켜서 처음부터 넣게다고 한다면 모를까..) 이렇게 메모리에는 공간의 낭비가 발생하게 됩니다.
순환 큐의 작동 방식
순환 큐는 index 값을 증가하되 값을 넣을 때는 modulo 연산자를 사용합니다. 그래서 index가 0인 값과 8인 값은 같은 공간에 들어가게 되지만 queue[0] 이 dequeue되지 않은 상태로 queue[8]의 값을 넣으려고 한다면 덮어 씌워지겠죠.
큐와 마찬가지로 front와 rear 포인터를 갖고 있습니다.(포인터가 int *front, *rear로 관리되기 때문에 포인터가 아니라 그 index를 가리키고 있기 때문에 포인터라고 표현하는 것입니다.) front는 값이 있는 제일 앞을 가리키고 rear는 값이 있는 가장 끝을 가리킵니다. 그래서 Enqueue 시에는 rear 값이 늘어나고 dequeue 시에는 front 값이 늘어나겠죠? 물론 일반 큐에서 front, rear은 계속 증가하지만 순환 큐에서 front와 rear은 0~순환큐의 크기 사이의 값입니다.
여기까지는 일반 큐와 같지만 순환 큐의 경우에는 enqueue시에는 남는 공간이 있는지(= 꽉 차지는 않았는지), dequeue시에는 비어 있지 않은지를 확인하는 작업을 추가로 진행해야 합니다. 꽉 차 있을 때 enqueue를 하면 원래 있는 값에 overwrite가 되기 때문이고 비어 있는 큐를 dequeue하려고 하면 에러기 때문입니다.
순환 큐에 대한 코드는 아래와 같이 짤 수 있습니다. 코드 복사를 원하시면 더보기를 누르시면 됩니다.
#include <iostream>
#define SIZE 8 /* Size of Circular Queue */
using namespace std;
class Queue{
private:
int elements[SIZE], front, rear;
public:
Queue(){
front = -1;
rear = -1;
}
bool isFull(void); // check if queue is full
bool isEmpty(void); // check if queue is empty
void enqueue(int element); // enqueue element
int dequeue(void); // dequeue element
void printQueue(void); // display queue
};
bool Queue::isFull(){
if(front == rear + 1){ return true; }
if(front == 0 && rear == SIZE - 1){
return true;
}
return false;
}
bool Queue::isEmpty(){
if(front == -1){
return true;
} else{
return false;
}
}
void Queue::enqueue(int ele){
if(!isFull()){
if(front == -1){
front = 0;
}
rear = (rear + 1) % SIZE;
elements[rear] = ele;
cout << ele << " inserted" << endl;
} else{
cout << "Circular Queue is full" << endl;
}
}
int Queue::dequeue(){
int ele;
if(!isEmpty()){
ele = elements[front];
if(front == rear){
// when queue is empty after dequeing
front = -1;
rear = -1;
} else{
front = (front + 1) % SIZE;
}
return ele;
} else{
cout << "Circular Queue is empty" << endl;
return -1;
}
}
void Queue::printQueue(){
if(!isEmpty()){
for(int i = front; i != rear; i = (i + 1) % SIZE){
cout << elements[i] << " ";
}
cout << elements[rear];
} else{
cout << "Circular Queue is empty" << endl;
}
}
int main(void){
Queue que;
que.dequeue(); // fails because queue is empty
for(int i = 0; i < SIZE; i++){
que.enqueue(i * 3 + 1);
}
que.enqueue(100); // fails because queue is full
que.printQueue();
int deqEle = que.dequeue();
if(deqEle > -1){
cout << endl;
cout << "Dequeued Element : " << deqEle << endl;
}
que.enqueue(0);
que.printQueue();
cout << endl;
return 0;
}
'CS > 알고리즘' 카테고리의 다른 글
[프로그래머스] 스킬트리 (배열) (0) | 2020.07.02 |
---|---|
[프로그래머스] 멀쩡한 사각형 (일차함수 & 자료형) (0) | 2020.07.02 |
[프로그래머스] 124 나라의 숫자 (재귀법) (2) | 2020.06.28 |
[프로그래머스] Level 1에서 볼 만한 문제 (0) | 2020.06.17 |
[프로그래머스] 탑 (0) | 2020.05.08 |
- Total
- Today
- Yesterday
- 삼성
- 코딩테스트
- 졸업작품
- 컴공졸작
- 코테
- ios
- 소프트웨어역량시험
- TableView
- 인턴
- 데이터분석
- 프로그래머스
- 부캠
- nosql
- 소프트웨어아카데미
- OS
- SWIFT
- 컴퓨터공학
- 보안
- firebase
- C++
- 삼성소프트웨어아카데미
- 알고리즘
- 부스트캠프
- 부스트캠프2020
- 개발자인턴
- 커넥트재단
- RxSwift
- 운영체제
- swacademy
- 컴과졸작
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |