嘿我试图在javascript中实现最小堆,但我有一个关于删除min的算法的问题。我在内部使用数组来表示堆。当我向下渗透时,停止条件应该是什么?在我的代码中,我将它放在2 * k< = this.size,所以它会向下传播到最后一个元素,但它没有感觉到#34;正确",是否有更好的停止条件?提前谢谢!
this.removeMin = function () {
//replace root with last element and percolate downwards
var min = this._heap[1],
k,
left,
right;
this._heap[1] = this._heap.pop();
this.size--;
k = 1;
while ( ( 2 * k ) <= this.size) {
left = 2 * k;
right = 2 * k + 1;
if (this._heap[k] > this._heap[left] && this._heap[k] > this._heap[right]) {
if (this._heap[left] <= this._heap[right]) {
swap(this._heap, k, left);
k = left;
} else {
swap(this._heap, k, right);
k = right;
}
} else if (this._heap[k] > this._heap[left]) {
swap(this._heap, k, left);
k = left;
} else {
swap(this._heap, k, right);
k = right;
}
}
return min;
};
答案 0 :(得分:1)
我认为你错过了一个条件。当k元素小于右边和左边时,向下必须停止。 必须是:
if (this._heap[k] > this._heap[left] && this._heap[k] > this._heap[right]) {
if (this._heap[left] <= this._heap[right]) {
swap(this._heap, k, left);
k = left;
} else {
swap(this._heap, k, right);
k = right;
}
} else if (this._heap[k] > this._heap[left]) {
swap(this._heap, k, left);
k = left;
} else if(this._heap[k] < this._heap[right]) {
swap(this._heap, k, right);
k = right;
}else{
break;
}
答案 1 :(得分:0)
为什么要一次又一次地编写比较代码。共享以下代码以供参考,以优化您的代码,您可以将其替换为while循环。
.....
while (2 * k <= this.size) {
let j = 2 * key;
if (j < this.size && less(j, j + 1)) j++; // find smallest child
if (!less(k, j)) break; // check parent is lesser than smallest child or not
exch(k, j); //if parent is bigger then exchange
k = j; //keep checking untill reaches to the end(this.size)
}
.....
function less(i, j){
if(this._heap[j] < this._heap[i] < 0) return true;
else return false;
}
function exch(i, j){
let temp = this._heap[i];
this._heap[i] = this._heap[j];
this._heap[j] = temp;
}
希望这行得通。