繁体   English   中英

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

[英]Kth smallest element greater than or equal to x in a min 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);
}

我不明白为什么节点的右孩子的计数没有减少?

计数不会减少,因为当您朝右子树前进时,当前节点被视为“k-1”个较小元素之一,而当我们向左移动时,当前节点不包含在“k”个最小元素中。

我同意@Bugaboo 的观点,即这里的代码有点误导,尽管接受的答案确实提供了合理的解释。

我发现这里的解决方案提供了更清晰的解释。 一旦节点本身与 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);
    }
}

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM