我在Skiena的手册中有代码:
int heap_compare(priority_queue *q, int i, int count, int x)
{
if ((count <= 0) || (i > q->n)) return(count);
if (q->q[i] < x) {
count = heap_compare(q, pq_young_child(i), count-1, x);
count = heap_compare(q, pq_young_child(i)+1, count, x);
}
return(count);
}
我不明白为什么计数不为节点的右子项递减?
答案 0 :(得分:1)
count
没有更新,因为它已经为当前节点减少了一次,并且该值被传递到左节点的 heap_compare
方法。并且从左节点的 heap_compare
返回的值被分配给 count
,因此无需再次递减。可以重写如下。
int heap_compare(priority_queue *q, int i, int count, int x)
{
if ((count <= 0) || (i > q->n)) return(count);
if (q->q[i] < x) {
count = count-1;
count = heap_compare(q, pq_young_child(i), count, x);
count = heap_compare(q, pq_young_child(i)+1, count, x);
}
return(count);
}
答案 1 :(得分:0)
计数不会减少,因为当您走向右子树时,当前节点被计为“k-1”个较小元素之一,当我们向左移动时,当前节点不包含在“k”中最小元素。
答案 2 :(得分:0)
我同意@Bugaboo的观点,尽管接受的答案的确提供了合理的解释,但是这里的代码有些误导。
我找到了解决方法here 提供了更清晰的解释。一旦将节点本身与x进行比较,计数器就会更新,然后算法会移动 伪代码由@Saeed Amiri提供:
% determine if the k-th smallest element in a min-heap is less than a given number x
void CheckNode(Node node,int k, int x, ref int counter)
{
if (node.value > x)
{
counter++;
if (counter >= k)
return;
CheckNode(node.Left, k, x, ref counter);
CheckNode(node.Right,k, x, ref counter);
}
}