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

标签 c heap min-heap

我不太明白为什么我的removeEntry 函数不起作用。我正在尝试为优先级队列 ADT 实现最小堆。它使用 void * 的数组。我已经验证向队列添加元素是有效的。由于某种原因,它无法正确堆积。

/* 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;
}

这是添加函数

void addEntry(PQ *pq, void *entry)
{
    assert(pq != NULL);

    int idx = pq->count;

    if(pq->count == pq->length)
        pq = realloc(pq, sizeof(PQ *) * (pq->length * 2));

    pq->data[idx] = entry;

    /* If the last element is greater than its parents, then swap them */
    while(idx != 0 && pq->compare(pq->data[PARENT(idx)], pq->data[idx]) > 0)
    {
        swap(pq->data[PARENT(idx)], pq->data[idx]);

        idx = PARENT(idx);
    }

    pq->count++;
    return;
}

最佳答案

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

关于c - 如何从C中的最小堆中删除第一个元素?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54994035/

相关文章:

c++ - 如何在不重新建立堆不变量两次的情况下有效地替换堆顶元素?

c++ - 查找最小堆中的最大元素

java - 使用最小堆实现优先级队列

C:尝试实现 minHeapSort 然后打印它 - 无法使 for 条件正常工作

c - for 循环中的条件表达式无效

c - 展开带引号的字符串内的整数宏

MySQL C API - 返回零行的查询的返回值是多少

c - 如果 char 被签名, "char foo = 255"是未定义的行为吗?

c++ - 为什么 c++ 中的堆被实现为算法而不是容器?

algorithm - 我用于构建最小堆的 Heapsort 算法有什么问题?