没有指针的递归结构?(霍夫曼)

Recursive struct without pointers? (Huffman)

本文关键字:霍夫曼 结构 递归 指针      更新时间:2023-10-16

我以这种方式定义了二进制树:

struct btree {
    int x;
    btree* left_child = nullptr;
    btree* right_child = nullptr;
};

然后,我有一个浮子的向量(prob_distr),然后将每个浮子变成一片叶子,然后将所有叶子放入优先级队列(使用自定义排序功能,但在这里没关系)。

>
auto comp = [] (btree &a, btree &b) -> bool { return a.x > b.x; };
priority_queue<btree, vector<btree>, decltype(comp)> q(comp);
for(auto t: prob_distr)
{
    btree leaf;
    leaf.x = t;
    q.push(leaf);
}

对于Huffman算法,我然后在优先队列上循环直到仅剩下1个元素:我将2个节点放在队列中,我在小时候使用这两个节点创建了一个新节点,我放了这些新节点进入队列。

while(q.size() >= 2)
{
    btree left = q.top(); q.pop();
    btree right = q.top(); q.pop();
    btree root;
    root.x = left.x + right.x;
    root.left_child = &left;
    root.right_child = &right;
    q.push(root);
}

问题在于我对leftright二进制树有指针,并且在脱离时循环时会删除这些树。然后,我没有指出指针。有什么方法可以解决这个问题,例如,拥有一个存储孩子树的结构,而不仅仅是指针,或者将节点存储在其他地方而没有它的地方变得太复杂了?

您需要在此处使用指针,因为必须在编译时知道结构的大小。如果您将struct本身作为成员变量,则内存要求将递归到Infinity。

您需要用new动态分配内存。分配了用new分配的内存,直到您使用delete明确释放它。只需写

root.left_child = new btree(left);
root.right_child = new btree(right);

如前所述,您还需要使用delete来释放孩子的记忆。请注意,不要制作未被删除的孩子的副本,也不要删除仍在其他地方使用的儿童。考虑使用智能指针。