우선순위 큐(Priority Queue)

Doozuu·2023년 3월 21일
0

📌 Priority Queue

각 요소가 그에 해당하는 우선순위를 가지는 데이터 구조.
더 높은 우선순위를 가진 요소가 더 낮은 우선순위를 가진 요소보다 먼저 처리된다.



구현

방법 1. 배열을 이용해 구현.

리스트를 전부 순회하면서 우선순위가 높은 것을 찾아야 하기 때문에 비효율적이다.
시간 복잡도 O(n)


방법 2. 힙을 이용해 구현.

min binary heap의 경우 root에 있는 것이 가장 우선순위가 높기 때문에 전부 순회하지 않고도 바로 찾을 수 있다.(효율적임.)


삽입 : enqueue, 삭제 : dequeue

  • min binary heap에서 노드 클래스가 추가된다.(priority 속성 추가)
  • 우선 순위가 동일한 경우는 속성에 insertTime을 추가해서 더 빨리 온 사람이 먼저 처리되도록 추가해줄 수도 있다.
class PriorityQueue {
    constructor(){
        this.values = [];
    }
    enqueue(val, priority){
        let newNode = new Node(val, priority);
        this.values.push(newNode);
        this.bubbleUp();
    }
    bubbleUp(){
        let idx = this.values.length - 1;
        const element = this.values[idx];
        while(idx > 0){
            let parentIdx = Math.floor((idx - 1)/2);
            let parent = this.values[parentIdx];
            if(element.priority >= parent.priority) break;
            this.values[parentIdx] = element;
            this.values[idx] = parent;
            idx = parentIdx;
        }
    }
    dequeue(){
        const min = this.values[0];
        const end = this.values.pop();
        if(this.values.length > 0){
            this.values[0] = end;
            this.sinkDown();
        }
        return min;
    }
    sinkDown(){
        let idx = 0;
        const length = this.values.length;
        const element = this.values[0];
        while(true){
            let leftChildIdx = 2 * idx + 1;
            let rightChildIdx = 2 * idx + 2;
            let leftChild,rightChild;
            let swap = null;

            if(leftChildIdx < length){
                leftChild = this.values[leftChildIdx];
                if(leftChild.priority < element.priority) {
                    swap = leftChildIdx;
                }
            }
            if(rightChildIdx < length){
                rightChild = this.values[rightChildIdx];
                if(
                    (swap === null && rightChild.priority < element.priority) || 
                    (swap !== null && rightChild.priority < leftChild.priority)
                ) {
                   swap = rightChildIdx;
                }
            }
            if(swap === null) break;
            this.values[idx] = this.values[swap];
            this.values[swap] = element;
            idx = swap;
        }
    }
}

class Node {
    constructor(val, priority){
        this.val = val;
        this.priority = priority;
    }
}

let ER = new PriorityQueue();
ER.enqueue("common cold",5)
ER.enqueue("gunshot wound", 1)
ER.enqueue("high fever",4)
ER.enqueue("broken arm",2)
ER.enqueue("glass in foot",3)
profile
모든게 새롭고 재밌는 프론트엔드 새싹

0개의 댓글