我找到了一个实现并且正在编写代码,其中一部分对我来说似乎不清楚。
struct graph {
int n; /* number of vertices */
int m; /* number of edges */
struct successors {
int d; /* number of successors */
int len; /* number of slots in array */
char is_sorted; /* true if list is already sorted */
int list[1]; /* actual list of successors */
} *alist[1];
};
graph_add_edge函数中的
/* do we need to grow the list? */
while (g->alist[u]->d >= g->alist[u]->len) {
g->alist[u]->len *= 2;
g->alist[u] =
realloc(g->alist[u],
sizeof(struct successors) + sizeof(int) * (g->alist[u]->len - 1));
}
为什么长度必须加倍?为什么甚至需要?是不是总是d + 1(继承人数+ 1)才能为下一个项目腾出空间?
答案 0 :(得分:2)
因为每次需要更多内存而不是仅增加1个内存时,在CPU时间方面的成本会降低一倍。
在后一种情况下,将为每个新添加的边缘调用realloc
,realloc
非常昂贵。想象一下,你有128条边:realloc
将被调用128次,但如果每次加倍,它只会被称为7 = log2(128)
次。
此外,realloc
很可能在原始内存部分越长的时候就越慢,因为realloc
可能会将旧的内存部分缓冲区复制到一个新的更大的内存部分缓冲区,并且该部分越长,越长复制将采取。