【问题标题】:Why are my MaxHeapify and BuildMaxHeap procedures failing to organise a heap?为什么我的 MaxHeapify 和 BuildMaxHeap 过程无法组织堆?
【发布时间】:2017-01-11 10:50:26
【问题描述】:

在我的堆的 ansi-c 实现中,我有两个过程:

void MaxHeapify(Heap * h, int i)
{
    int l = Left(i);
    int r = Right(i);
    int L, tmp;

    if(l < h->heapsize && h->data[l] > h->data[i]) L = l;
    else L = i;

    if(r < h->heapsize && h->data[r] > h->data[L]) L = r;
    if(L != i)
    {
        tmp = h->data[i];
        h->data[i] = h->data[L];
        h->data[L] = tmp;
        MaxHeapify(h, L);
    }
}

void BuildMaxHeap(Heap * h)
{
    int i;
    h->heapsize = h->length;
    for(i = h->length / 2; i >= 0; i--)
    MaxHeapify(h, i);
}

还有main.c

int main(int argc, char *argv[])
{
    int i;
    Heap h;
    int tab[] = {4,1,3,2,16,9,10,14,8,7};
    HeapInit(&h, tab, 10);
    for(i = 0; i < 10; i++) printf("%d ", h.data[i]);
    printf("\n");
    BuildMaxHeap(&h);
    for(i = 0; i < 10; i++) printf("%d ", h.data[i]);

    return 0;
}

我有奇怪的输出: 16 14 10 10 8 1 4 2 3 7 我检查了几次代码,但没有发现任何问题。

更正的节点索引返回函数:

int Left(int i)
{
    return 2*i+1;
}
int Right(int i)
{
    return 2*i+2;
}

【问题讨论】:

  • 显示您的 Right()Left() 函数。
  • 您检查lr 是否在界限内似乎是错误的。例如,您正在使用r &lt;= h-&gt;heapsize。但是您的 data 数组是从 0 开始的。所以这可能应该是一个“小于”比较:r &lt; h-&gt;heapsize. 我认为您正在访问h-&gt;data[10],这超出了您的堆范围。
  • int Left(int i) { return 2*i; } int Right(int i) { return 2*i+1; }
  • @JimMischel 更改了这些,输出更好,但仍然...16 14 9 10 8 1 4 2 3 7 /// 理想当然是:16 14 10 8 7 9 3 2 4 1
  • 如果你的根节点在索引 0 处(看起来是),那么左边应该是(2*i)+1,右边应该是(2*i)+2

标签: data-structures ansi-c


【解决方案1】:

@JimMischel 在 cmets 中发布了正确答案。它是基于从 1 开始索引的伪代码编写的,这让我很困惑。正确的代码发布(通过编辑)有问题。

【讨论】:

    猜你喜欢
    • 2015-05-01
    • 2018-02-08
    • 1970-01-01
    • 2016-05-09
    • 1970-01-01
    • 2014-05-22
    • 1970-01-01
    • 1970-01-01
    • 2013-03-19
    相关资源
    最近更新 更多