▼ 비선형 자료 구조 그래프와 트리에 대한 내용
[CS] 자료 구조의 분류 - 비선형 자료 구조 #1 (그래프, 트리)
📌 삽입
📌 삭제
enqueue(): 요소는 우선순위 큐에 삽입될 때 해당 요소의 우선순위에 따라 정확한 위치에 삽입된다. 일반적으로 우선순위가 높은 요소는 큐의 앞쪽에 위치하게 된다.
dequeue(): 우선순위 큐에서는 주로 우선순위가 가장 높은 요소를 삭제하고 반환하는 연산이 수행된다. 이 연산을 "최소값 추출(Min Extract)" 또는 "최대값 추출(Max Extract)"이라고도 한다.
peek(): Queue에서 최대 우선순위 요소를 반환한다. 최대 우선순위 값은 항상 루트에 있으므로 루트 값을 반환한다.
구현 방법 | 삽입 | 삭제 |
---|---|---|
배열 | O(1) | O(N) |
연결 리스트 | O(1) | O(N) |
정렬된 배열 | O(N) | O(1) |
정렬된 연결 리스트 | O(N) | O(1) |
힙 | O(logN) | O(logN) |
class PriorityQueue {
constructor() {
this.heap = [];
}
// 요소 삽입
enqueue(value, priority) {
const element = { value, priority };
this.heap.push(element);
this.bubbleUp();
}
// 가장 우선순위가 높은 요소 추출
dequeue() {
if (this.isEmpty()) return null;
if (this.heap.length === 1) return this.heap.pop();
const min = this.heap[0];
this.heap[0] = this.heap.pop();
this.sinkDown();
return min;
}
// 우선순위 큐가 비어 있는지 확인
isEmpty() {
return this.heap.length === 0;
}
// 요소를 힙 상단으로 이동시키는 메서드 (삽입 시)
bubbleUp() {
let currentIndex = this.heap.length - 1;
const currentElement = this.heap[currentIndex];
while (currentIndex > 0) {
const parentIndex = Math.floor((currentIndex - 1) / 2);
const parentElement = this.heap[parentIndex];
if (currentElement.priority >= parentElement.priority) break;
// 부모와 자식 요소 교환
this.heap[currentIndex] = parentElement;
this.heap[parentIndex] = currentElement;
currentIndex = parentIndex;
}
}
// 요소를 힙 하단으로 이동시키는 메서드 (추출 시)
sinkDown() {
let currentIndex = 0;
const length = this.heap.length;
const currentElement = this.heap[0];
while (true) {
const leftChildIndex = 2 * currentIndex + 1;
const rightChildIndex = 2 * currentIndex + 2;
let swapIndex = null;
if (leftChildIndex < length) {
const leftChild = this.heap[leftChildIndex];
if (leftChild.priority < currentElement.priority) {
swapIndex = leftChildIndex;
}
}
if (rightChildIndex < length) {
const rightChild = this.heap[rightChildIndex];
if (
(swapIndex === null && rightChild.priority < currentElement.priority) ||
(swapIndex !== null && rightChild.priority < this.heap[swapIndex].priority)
) {
swapIndex = rightChildIndex;
}
}
if (swapIndex === null) break;
// 부모와 자식 요소 교환
this.heap[currentIndex] = this.heap[swapIndex];
this.heap[swapIndex] = currentElement;
currentIndex = swapIndex;
}
}
}
// 우선순위 큐 사용 예시
const priorityQueue = new PriorityQueue();
priorityQueue.enqueue('Task 1', 3);
priorityQueue.enqueue('Task 2', 1);
priorityQueue.enqueue('Task 3', 2);
console.log(priorityQueue.dequeue()); // { value: 'Task 2', priority: 1 }
console.log(priorityQueue.dequeue()); // { value: 'Task 3', priority: 2 }
console.log(priorityQueue.dequeue()); // { value: 'Task 1', priority: 3 }
console.log(priorityQueue.isEmpty()); // true