如何从C中的最小堆中删除第一个元素?

时间:2019-03-05 01:15:04

标签: c heap min-heap

我不太清楚为什么我的removeEntry函数不起作用。我正在尝试为优先级队列ADT实现最小堆。它使用一个空*的数组。我已经验证了将元素添加到队列中是否可行。由于某些原因,它无法正确堆积。

select d.*
from dams d cross join
     (values (0), (1), (2)) v(i);

这是我用来获取左右“孩子”索引的宏。

/* Removes the root element from the queue */
void *removeEntry(PQ *pq)
{   
    assert(pq != NULL);

    if(pq->count == 0)
        return NULL;

    /* idx is 0 since we're only deleting the first element */
    int idx = 0;
    int left = L_CHILD(idx), right, child;

    void * min = pq->data[0];

    pq->data[0] = pq->data[pq->count-1];

    pq->count--;

    while(left <= pq->count-1)
    {
        left = L_CHILD(idx);
        right = R_CHILD(idx);

        child = left;

        /* Check if right child exists */
        if(right <= pq->count-1)
        {
            /* Set child to the smaller child */
            if(pq->compare(pq->data[right], pq->data[left]) < 0)
                child = right;
        }

        /* If the data at idx is greater than it's child, then switch    them */
        if(pq->compare(pq->data[idx], pq->data[child]) > 0)
        {
            swap(pq->data[idx], pq->data[child]);
            idx = child;
        }
        else
            break;
        }

        return min;

}

这也是交换功能,以防万一有人好奇

#define L_CHILD(id) ((2*(id))+1)
#define R_CHILD(id) ((2*(id))+2)

这是添加功能

static void swap(void *a, void *b)
{
    void * temp;
    temp = a;
    a = b;
    b = temp;
}

1 个答案:

答案 0 :(得分:0)

  1. 您的返回条件在while循环范围内。结果,该函数将在第一次迭代中返回,并且无法正确进行堆化。
  2. 处理左时的情况<= pq-> count-1,但L_CHILD(left)> = pq-> count-1。