Javascript는 Priority Queue 내장함수가 없어서 직접 만들어서 써야 한다.
Binary 방식으로 메모리를 관리 한다.
코드를 만들 때 주의 해야 할 것은
1. pop 할때 내부 Array의 사이즈를 항상 1로 유지 하는 것
2. Array 자체의 사이즈가 2일 때는 1상태로 돌려주는 부분이다.
class PriorityQ {
constructor() {
this.arr = new Array();
this.arr.push('');
}
push(cost, elem) {
this.arr.push([cost, elem]);
let curPosition = this.arr.length-1;
while (1 < curPosition && this.arr[curPosition][0] < this.arr[Math.floor(curPosition / 2)][0]) {
let tmp = this.arr[Math.floor(curPosition / 2)];
this.arr[Math.floor(curPosition / 2)] = this.arr[curPosition];
this.arr[curPosition] = tmp;
curPosition = Math.floor(curPosition / 2);
}
}
pop(){
if(this.arr.length <= 1) return null;
let curPosition = 1;
let last = this.arr[curPosition];
if(2 < this.arr.length) this.arr[curPosition] = this.arr.pop();
else this.arr.pop();
while (curPosition * 2 < this.arr.length) {
if (curPosition * 2 + 1 < this.arr.length && this.arr[curPosition * 2 + 1][0] <= this.arr[curPosition * 2][0] && this.arr[curPosition * 2 + 1][0] < this.arr[curPosition][0]) { //양쪽이 있고 왼쪽이 작을 경우
let tmp = this.arr[curPosition * 2 + 1];
this.arr[curPosition * 2 + 1] = this.arr[curPosition];
this.arr[curPosition] = tmp;
curPosition = curPosition * 2 + 1;
} else if (this.arr[curPosition * 2][0] < this.arr[curPosition][0]){
let tmp = this.arr[curPosition * 2];
this.arr[curPosition * 2] = this.arr[curPosition];
this.arr[curPosition] = tmp;
curPosition = curPosition * 2;
} else {
break;
}
}
return last;
}
}
사용 방법은 아래와 같다.
여기서 elem은 어떤 객체든 상관은 없다.
let pq = new PriorityQ();
pq.push(1000, [1, 1]);
pq.push(1, [1, 1]);
pq.push(2, [1, 1]);
pq.push(3, [1, 1]);
pq.push(-10000, [1, 1]);
pq.push(19999, [1, 1]);
pq.push(4, [1, 1]);
pq.push(0, [1, 1]);
console.assert(pq.pop()[0]==-10000, '1 fail');
console.assert(pq.pop()[0]==0, '2 fail');
console.assert(pq.pop()[0]==1, '3 fail');
console.assert(pq.pop()[0]==2, '4 fail');
pq.push(-1000, [1, 1]);
pq.push(1, [1, 1]);
pq.push(2, [1, 1]);
pq.push(3, [1, 1]);
console.assert(pq.pop()[0]==-1000, '5 fail');
console.assert(pq.pop()[0]==1, '6 fail');
console.assert(pq.pop()[0]==2, '7 fail');
console.assert(pq.pop()[0]==3, '8 fail');
console.assert(pq.pop()[0]==3, '9 fail');
pq.push(-10000, [1, 1]);
console.assert(pq.pop()[0]==-10000, '10 fail');
pq.push(200000, [1, 1]);
console.assert(pq.pop()[0]==4, '11 fail');
console.assert(pq.pop()[0]==1000, '12 fail');
console.assert(pq.pop()[0]==19999, '13 fail');
console.assert(pq.pop()[0]==200000, '14 fail');
console.assert(pq.pop()==null, '15 fail');
Max Heap과 Min Heap을 선택 할 수있는 부분을 넣어서 업데이트 한다.
class PriorityQ {
constructor(asc = true) { //Min heap true, Max heap false
this.arr = new Array();
this.arr.push('');
this.asc = asc;
}
_compare(a, b){
if (this.asc) {
return a < b;
} else {
return a > b;
}
}
_compareEq(a, b){
if (this.asc) {
return a <= b;
} else {
return a >= b;
}
}
push(cost, elem) {
this.arr.push([cost, elem]);
let curPosition = this.arr.length-1;
while (1 < curPosition && this._compare(this.arr[curPosition][0], this.arr[Math.floor(curPosition / 2)][0]) ) {
let tmp = this.arr[Math.floor(curPosition / 2)];
this.arr[Math.floor(curPosition / 2)] = this.arr[curPosition];
this.arr[curPosition] = tmp;
curPosition = Math.floor(curPosition / 2);
}
}
pop(){
if(this.arr.length <= 1) return null;
let curPosition = 1;
let last = this.arr[curPosition];
if(2 < this.arr.length) this.arr[curPosition] = this.arr.pop();
else this.arr.pop();
while (curPosition * 2 < this.arr.length) {
if (curPosition * 2 + 1 < this.arr.length && this._compareEq(this.arr[curPosition * 2 + 1][0], this.arr[curPosition * 2][0]) && this._compare(this.arr[curPosition * 2 + 1][0],this.arr[curPosition][0])) { //양쪽이 있고 왼쪽이 작을 경우
let tmp = this.arr[curPosition * 2 + 1];
this.arr[curPosition * 2 + 1] = this.arr[curPosition];
this.arr[curPosition] = tmp;
curPosition = curPosition * 2 + 1;
} else if (this._compare(this.arr[curPosition * 2][0],this.arr[curPosition][0])){
let tmp = this.arr[curPosition * 2];
this.arr[curPosition * 2] = this.arr[curPosition];
this.arr[curPosition] = tmp;
curPosition = curPosition * 2;
} else {
break;
}
}
return last;
}
}
728x90
반응형
'Problem Solving' 카테고리의 다른 글
Union find (0) | 2020.09.15 |
---|---|
지형 이동 (0) | 2020.09.14 |
Hyper V Ubuntu safe mode (grub & cd boot & gparted) (0) | 2020.09.13 |
all subsets of a word (모든 부분 집합 찾기) (0) | 2020.09.13 |
1022. Sum of Root To Leaf Binary Numbers (0) | 2020.09.08 |