在最小堆中大于或等于x的第K个最小元素

时间:2017-01-03 23:12:27

标签: algorithm heap

我在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);
}

我不明白为什么计数为节点的右子项递减?

3 个答案:

答案 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);
    }
}