큐- 4
이 내용은 'Learning JavaScript Data Structures and Algorithms'(로이아니 그로네르 저, 이일웅 역) 책의 내용을 제 생각과 함께 정리한 글입니다.
틀린 내용 혹은 수정이 필요한 내용이 있다면 말씀해주시면 감사하겠습니다.
-
큐는 FIFO(First In First Out = 선입선출) 원리에 따라 정렬된 컬렉션이다.
-
새 원소는 뒤로 들어가서 앞에서 빠져나가는 구조다.
-
따라서 마지막에 추가된 원소는 큐의 뒷부분에서 제일 오래 기다려야 한다.
줄서기를 떠올려보자. 영화관에서 줄을 서 있을 때 맨 앞의 사람이 가장 먼저 표를 사는 것은 당연한 일이다.
큐 만들기
-
큐에서 사용할 메소드는 다음과 같다.
-
enqueue(element)
: 큐의 뒤쪽에 원소(들)를 추가한다. -
dequeue()
: 큐의 첫 번째 원소(큐의 맨 앞쪽에 위치한 원소)를 반환하고 큐에서 삭제한다. -
front()
: 큐의 첫 번째 원소를 반환하되 큐 자체는 그대로 놔둔다. (peek()
과 비슷) -
isEmpty()
: 큐가 비어있으면true
, 아니면false
를 반환한다. -
size()
: 큐의 원소 개수를 반환한다. 배열의length
와 같다.
function Queue() {
var items = [];
this.enqueue = function (element) {
items.push(element);
};
this.dequeue = function () {
return items.shift();
};
this.front = function () {
return items[0];
};
this.isEmpty = function () {
return items.length === 0;
};
this.size = function () {
return items.length;
};
this.print = function () {
console.log(items);
};
}
Queue와 Stack 클래스는 매우 유사하다. 적용하는 원리가 FIFO, LIFO로 다르기 때문에
dequeue
와 마찬가지로front
메소드만 다르다.
- 결과를 확인해보자.
const queue = new Queue();
console.log(queue.isEmpty()); // true
queue.enqueue('John');
queue.enqueue('Jack');
queue.enqueue('Camilla');
queue.print(); // [ 'John', 'Jack', 'Camilla' ]
console.log(queue.size()); // 3
console.log(queue.isEmpty()); // false
queue.dequeue();
queue.dequeue();
queue.print(); // [ 'Camilla' ]
우선순위 큐
- 원소가 우선 순위에 따라 추가되고 삭제된다.
비행기 탑승을 떠올려보자. 1등석과 비즈니스석 승객은 항상 이코노미석 승객보다 우선순위가 높다.
- 우선순위 큐는 우선순위를 설정해 원소를 정확한 위치에 추가하는 것, 그리고 추가는 순서대로 하되 삭제만 우선순위에 따르는 것, 두 가지 방법으로 구현할 수 있다. 먼저 전자를 보자.
function PrirorityQueue() {
let items = [];
function QueueElement(element, priority) {
this.element = element;
this.priority = priority; // 우선순위(priority)가 추가됨
}
this.enqueue = function (element, priority) {
let queueElement = new QueueElement(element, priority);
if (this.isEmpty()) {
items.push(queueElement); // 큐가 비어있다면 원소를 그냥 넣는다.
}
// general case
else {
let added = false;
for (let i = 0; i < items.length; i++) {
// 만약 우선순위가 더 높은 원소가 들어왔다면
if (queueElement.priority < items[i].priority) {
// 해당 위치에 원소를 추가한다.
items.splice(i, 0, queueElement);
added = true;
break; // 루프문 종료
}
}
// 만약 새 원소의 우선순위가 가장 낮다면
if (!added) {
items.push(queueElement);
}
}
};
this.isEmpty = function () {
return items.length === 0;
};
this.print = function () {
console.log(items);
};
}
const priorityQueue = new PrirorityQueue();
priorityQueue.enqueue('John', 2);
priorityQueue.enqueue('Jack', 1);
priorityQueue.enqueue('Camilla', 3);
priorityQueue.print();
// 실행결과: [ QueueElement { element: 'Jack', priority: 1 },
// QueueElement { element: 'John', priority: 2 },
// QueueElement { element: 'Camilla', priority: 3 } ]
-
이러한 로직으로 구현한 우선순위 큐를 최소 우선순위 큐(min priority queue)라고 부르는데, 우선순위 값이 낮으면 낮을수록(1이 가장 높은 우선순위다) 앞자리로 이동하기 때문이다.
-
반대로 우선순위 값이 크면 클수록 앞자리로 보내는 최대 우선순위 큐(max priority queue)도 있다.
환형 큐 (뜨거운 감자 게임)
-
뜨거운 감자(Hot Potato)게임 은 환형 큐(Circular Queue)의 대표적인 예다.
-
원을 그리고 서 있는 아이들이 뜨거운 감자를 옆 사람에게 최대한 빨리 전달하다가, 갑자기 모두 동작을 멈추고 그 때 뜨거운 감자를 손에 들고 있는 아이를 벌칙으로 퇴장시키는 게임이다. 최후의 1인(승자)이 남을 때까지 게임은 계속된다.
-
이를 코드로 구현해보자.
// Circular Queue (Hot Potato Game)
// nameList: 게임에 참여한 사람들의 이름, num: 큐를 순회할 횟수
function hotPotato(nameList, num) {
let queue = new Queue();
for (let i = 0; i < nameList.length; i++) queue.enqueue(nameList[i]);
let eliminated = '';
// 최후의 1인이 남을 때까지
while (queue.size() > 1) {
for (let i = 0; i < num; i++) queue.enqueue(queue.dequeue()); // 맨 앞의 원소를 꺼내어 맨 뒤로 넣는다.
eliminated = queue.dequeue(); // num만큼 반복이 끝난 후 뜨거운 감자를 들고 있던 사람을 퇴장시킨다.
console.log(`${eliminated}을(를) 게임에서 퇴장시킵니다.`);
}
return queue.front(); // 마지막 사람이 승자가 된다.
}
const names = ['John', 'Jack', 'Camilla', 'Ingrid', 'Carl'];
const winner = hotPotato(names, 7);
console.log(`승자는 ${winner} 입니다.`);
// 결과
// Camilla을(를) 게임에서 퇴장시킵니다.
// Jack을(를) 게임에서 퇴장시킵니다.
// Carl을(를) 게임에서 퇴장시킵니다.
// Ingrid을(를) 게임에서 퇴장시킵니다.
// 승자는 John 입니다.
hotPotato
함수의num
인자를 바꾸면 다른 결과를 반환할 것이다.
Author And Source
이 문제에 관하여(큐- 4), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@ken1204/큐-4저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)