簡體   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