큐는 '선입선출' , FIFO(First In First Out)의 개념을 가진 선행 자료구조이다. 스택은 입구와 출구가 동일하여 나중에 들어온 순서대로 나가는 구조지만, 큐는 입구와 출구가 달라 먼저 들어온 데이터가 먼저 나가는 구조이다.
놀이공원에서 놀이기구를 타기 위해서는 줄을 서야 하고 줄을 슨 순서대로 놀이기구에 탑승하게 된다. 이와 같은 예가 큐(Queue)이다.
class Queue {
constructor() {
this.queue = [];
this.front = 0;
this.rear = 0;
}
enqueue(value) {
this.queue[this.rear++] = value;
}
dequeue() {
const value = this.queue[this.front];
delete this.queue[this.front++]
return value;
}
peek() {
return this.queue[this.front];
}
size() {
return this.rear - this.front;
}
}
class Node {
constructor(value) {
this.next = null;
this.value = value;
}
}
class Queue {
constructor() {
this.head = null;
this.tail = null;
this.size = 0;
}
enqueue(value) {
const newNode = new Node(value);
if (!this.head) {
this.head = newNode;
this.tail = newNode;
} else {
this.tail.next = newNode;
this.tail = newNode;
}
this.size++;
}
dequeue() {
const value = this.head.value;
this.head = this.head.next;
this.size--;
return value;
}
peek() {
return this.head.value;
}
}
큐에서 deQueue() 함수를 사용하면 맨 앞에 있는 값이 반환되며 제거된다. 이때 front 값이 front += 1 되어 한 칸씩 밀려나게 되어 큐의 가용 범위가 줄어들고, 데이터가 꽉 차게 된다면 더 이상 공간을 활용할 수 없게 된다. 이 방식을 해결하기 위해서는 deQueue 되었을 때 front 값은 고정시키고 뒤에 있는 데이터들의 index를 한 칸씩 당기는 방법밖에 없다. 이 문제점을 보완하기 위해 나온 것이 원형 큐이다.
class CircularQueue {
constructor(maxSize) {
this.maxSize = maxSize;
this.queue = [];
this.front = 0;
this.rear = 0;
this.size = 0;
}
enqueue(value) {
if (this.isFull()) {
console.log('Queue if Full');
return;
}
this.queue[this.rear] = value;
this.rear = (this.rear + 1) % this.maxSize
this.size += 1;
}
dequeue() {
const value = this.queue[this.front];
delete this.queue[this.front];
this.front = (this.front + 1) % this.maxSize;
this.size -= 1;
return value;
}
isFull() {
return this.size === this.maxSize;
}
peek() {
return this.queue[this.front];
}
}