min-heap
作为 Dijkstra 算法的一部分,我正在用 C 语言编写 a的实现。我已经把所有细节都写下来了,我的测试程序通过了 valgrind 测试,但它在这个过程中分配了荒谬的内存量。最后的测试是在一个网格上INT_MAX
(INT_MAX
坐标只是整数),我SIGXCPU
在测试时会出错。即使我只是将16k
位置插入队列然后删除所有内容,它仍然需要很长时间并分配超过8 MB
. 当我在巨大的网格测试用例上运行它时,它可以500 MB
在我手动退出之前达到。会发生什么?这是我的代码的一部分:
struct position {
int x;
int y
};
typedef struct elt {
int priority;
int distance;
struct position p;
} *Elt;
typedef struct heap {
int size;
int capacity;
Elt *elts;
} *Heap;
void heap_insert(Heap h, Elt e, int *counter) {
if(h->capacity < (h->size + 2)) {
h->elts = realloc(h->elts, h->capacity * sizeof(Elt) * 2);
h->capacity *= 2;
}
h->elts[h->size] = malloc(sizeof(*Elt));
elt_assign(h->elts[h->size], e);
h->size++;
heapify(h->size, h->elts);
*counter = *counter + 1;
}
我所有的其他功能都一次性进行内存管理,在功能中进行,或者根本不进行。在这种情况下,初始大小是64
,但我从 开始得到了相同的效果1024
。我还尝试限制队列的大小,但无济于事。我很确定这不是我的堆积代码,但这是以防万一
static void floatDown(int n, Elt *a, int pos) {
Elt x = malloc(sizeof(struct elt));
elt_assign(x, a[pos]);
for(;;) {
if(Child(pos, 1) < n && a[Child(pos, 1)]->priority < a[Child(pos, 0)]->priority) {
if(a[Child(pos, 1)]->priority < x->priority) {
elt_assign(a[pos], a[Child(pos, 1)]);
pos = Child(pos, 1);
} else {
break;
}
} else if(Child(pos, 0) < n && a[Child(pos, 0)]->priority < x->priority) {
elt_assign(a[pos], a[Child(pos, 0)]);
pos = Child(pos, 0);
} else {
break;
}
}
elt_assign(a[pos], x);
free(x);
}
static void heapify(int n, Elt *a) {
for(int i = n - 1; i >= 0; i--) {
floatDown(n, a, i);
}
}
任何帮助将非常感激。