在树状结构中转发预留内存

时间:2012-05-10 09:39:34

标签: c++ memory-management vector tree

如何很好地保留树状结构的记忆?假设这将由STL向量实现:

struct Leaf
{
    int val;
};

struct Branch
{
    std::vector<Leaf> leaves;
};

现在,我可以为Branch es

的向量保留一些内存
std::vector<Branch> branches;
branches.reserve(10);

但是如何同时为leaves保留内存(例如在构建Branch个对象时)?

3 个答案:

答案 0 :(得分:2)

您可以考虑将整个树存储在一个数组中,可能是一个向量。假设您有一个结构Node

struct Node
{
    int val;
    vector<size_t> children;
};

vector<Node> tree;

然后tree[0]是树的根。每次要在某个节点中添加新分支时,让我们说tree[i],您可以这样做:

tree.resize(tree.size()+1);
tree[i].children.push_back(tree.size()-1);
// you can also set the value of the new node:
tree.back().val = 123;

然后,您可以通过从任何节点(包括根)开始并查看其子节点来轻松遍历树。

以下是使用DFS遍历树的示例:

void dfs(size_t x)
{
    // you can do sth here, for example:
    printf("node: %d, number of children: %d\n", x, tree[x].children.size());

    // go deeper in the tree to the node's children:
    for (size_t i=0; i<tree[x].children.size(); ++i)
        dfs(tree[x].children[i]);
}

// starting DFS from the root:
dfs(0);

这样您就可以为树保留内存:

tree.reserve(100);

答案 1 :(得分:1)

在初始化整个树之前(或者作为树的一部分),制作一些指向预初始化的空Leaf的指针。之后,您可以从堆栈中pop Leaf并将其附加到特定Branch(并使用所需的值填充Leaf ...)。当然,您应该将std::vector<Leaf>更改为std::vector<Leaf*>

当堆栈为空时,创建另一组空Leaf s。

答案 2 :(得分:1)

当您尝试为Branch es保留时,您会保留多少内存?它们中的每一个都包含一个std::vector,所以它的大小是可变的。

我的建议是实际构建一个充满(空)Branch es的向量,但同时保留他们Leaf的空间,就像这样:

如果为Branch类/ struct编写内存保留构造函数:

struct Branch{
    std::vector <Leaf> leaves;
    Branch (int expectedL = 10){
        leaves.reserve(expectedL);
    }
};

然后你可以这样做:

std::vector<Branch> branches(10);

std::vector<Branch> branches(10, 42);

不完全是你问的问题,但也许有帮助。