【发布时间】: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()函数。 -
您检查
l和r是否在界限内似乎是错误的。例如,您正在使用r <= h->heapsize。但是您的data数组是从 0 开始的。所以这可能应该是一个“小于”比较:r < h->heapsize.我认为您正在访问h->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。