如何很好地保留树状结构的记忆?假设这将由STL向量实现:
struct Leaf
{
int val;
};
struct Branch
{
std::vector<Leaf> leaves;
};
现在,我可以为Branch
es
std::vector<Branch> branches;
branches.reserve(10);
但是如何同时为leaves
保留内存(例如在构建Branch
个对象时)?
答案 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);
不完全是你问的问题,但也许有帮助。