【发布时间】:2020-09-04 13:46:44
【问题描述】:
这是一个最小堆的插入函数。我不明白为什么它不起作用。
void insertHeapMin(Heap* h, int x){
if(isFull(h)){
printf("heap is full\n");
return;
}
for(i=0; i<h->size;i++) //I don't wan't to insert one number more than once;
{
if(x==h->data[i]) return;
}
int pos = h->size;
h->data[pos]=x;
while(pos>0){
int parentPos = (pos-1)/2;
if (h->data[pos] < h->data[parentPos]){
int temp = h->data[pos];
h->data[pos] = h->data[parentPos];
h->data[parentPos] = temp;
pos = parentPos;
} else
break;
}
h->size++;
}
主要:
int a[] ={4,3,6,4,5};
size_t n = sizeof(a)/sizeof(a[0]);
Heap h;
initHeap(&h,100);
int i;
for(i=0;i<n;i++){
insertHeapMin(&h, a[i]);
}
for(i=0;i<n;i++){
printf("%d ",h.data[i]);
}
printf("\n");
它返回 3 4 6 5 1666986547。我真的看不出错误在哪里,当我修改 max-heap 的插入函数时它工作得很好,当没有重复元素时,仍然不知道如何修复重复元素的 for 循环。
【问题讨论】:
-
您不会两次插入一个元素,因此您的堆中的元素可能少于
n。当你打印出堆时,使用h.size作为限制。 -
看起来 1666986547 是一个未初始化的 int。你检查过
n吗?可能n太大而您不小心访问了a[5]。 -
(顺便说一下,重复的线性搜索会降低堆性能。从堆中弹出元素时处理重复可能会更好。)
-
堆未完全排序。它仅具有每个父级不大于其子级的条件。 (排序是通过将项目从堆中弹出并重新堆来实现的。)
-
如果要保持排序,可以从最初的迭代搜索中找到插入点进行重复。