为了提高计算速度,我需要在树中存储大量数据。一些节点应该包含内部点的平均属性而另一些不应该包含,例如典型的光节点只包含子节点的地址和典型的常规节点,这两个地址加上一些信息。我正在寻找一种智能方法,使用最少的内存将这两种节点存储在同一个树中。
我正在使用c。我首先使用结构(node.properties,node.Left,nodeRight等)构建我的树,但它需要太多内存(如果你熟悉结构,你可能会弄清楚原因),所以我有回到我的树的某种“内联”组织,在前两个插槽中存储子节点的地址,并且(最终)在以下插槽中存储其余信息。
所以我虽然有两种方法可以做到这一点。一种方法是预测节点总数(简单)并分配足够的内存以将所有节点存储为常规节点(子节点地址有2个插槽,信息有1个插槽)。另一种方法是在我们沿树下去时重新分配树数组。
第一个问题:在效率方面广泛使用realloc()真的是一件好事吗?
第二个问题:这样做是否有更聪明的方法(在记忆方面)?
答案 0 :(得分:0)
好吧,我认为我找到了妥协方案。首先确定树的大小,并且分配大小为2的指针数组X节点的数量。每个节点将有(1)[指向]一个整数数组,其中包含左子节点的索引,右子节点的索引和点数,以及(2)[指向]包含双精度数组的数组所有有用的信息。当例程构建树时,将根据节点的类型计算为“double”数组分配的空间。
到目前为止,这是我能想到的“最便宜”的解决方案。但是如果你能说服我转换(long)index_in_double很快,那么在数组中只能使用double。
答案 1 :(得分:0)
为了说明使用索引而不是指针的要点,请参阅使用(短)int索引的this hash table implementation,节省一些宝贵的位。 tiny_find()函数编译到这个程序集(GCC -O2):
.globl tiny_find
.type tiny_find, @function
tiny_find:
.LFB57:
.cfi_startproc
imull $98765, %edi, %ecx
movl $274877907, %edx
movl %ecx, %eax
mull %edx
movl $-1, %eax
shrl $6, %edx
imull $1000, %edx, %edx
subl %edx, %ecx
movzwl %cx, %ecx
movzwl table+4(,%rcx,8), %edx
cmpw $-1, %dx
je .L12
movzwl %dx, %eax
testb $1, table+7(,%rax,8)
jne .L19
jmp .L13
.p2align 4,,10
.p2align 3
.L21:
movzwl table+4(,%rax,8), %eax
cmpw $-1, %ax
je .L20
movzwl %ax, %eax
testb $1, table+7(,%rax,8)
je .L13
.L19:
cmpl table(,%rax,8), %edi
jne .L21
.L13:
movzbl table+6(,%rax,8), %eax
.L12:
rep
ret
.p2align 4,,10
.p2align 3
.L20:
movl $-1, %eax
ret
.cfi_endproc
.LFE57:
.size tiny_find, .-tiny_find
内循环(走链表)是L21和L13之间的部分。我不会说代码效率低下。