package lib; using Lambda; abstract PriorityQueue(Array<{prio:Float, val:T}>) { public inline function new() { this = []; } public function containsElement(element:T):Bool { return this.exists((e) -> e.val == element); } public function isEmpty():Bool { return this.length == 0; } public function insert(e:T, prio:Float) { this.push({prio: prio, val: e}); bubbleUp(this.length - 1); } public function extractMin():Null { if (this.length == 0) { return null; } swap(0, this.length - 1); var minElement = this.pop(); bubbleDown(0); return minElement.val; } private function bubbleUp(index:Int) { var parentIndex:Int = Math.floor((index - 1) / 2); if (index > 0 && this[index].prio < this[parentIndex].prio) { swap(index, parentIndex); bubbleUp(parentIndex); } } private function bubbleDown(index:Int) { var leftIndex = 2 * index + 1; var rightIndex = 2 * index + 2; var smallest = index; if (leftIndex < this.length && this[leftIndex].prio < this[smallest].prio) { smallest = leftIndex; } if (rightIndex < this.length && this[rightIndex].prio < this[smallest].prio) { smallest = rightIndex; } if (smallest != index) { swap(index, smallest); bubbleDown(smallest); } } private function swap(i:Int, j:Int) { var tmp = this[i]; this[i] = this[j]; this[j] = tmp; } }