【发布时间】:2021-09-10 13:10:37
【问题描述】:
我的一个程序需要一个树形结构。我知道以下两种实现方法:
- 递归,基于指针。
struct node
{
std::unique_ptr<T> data = nullptr;
std::vector<std::unique_ptr<node>> children = {};
};
// /> leaf_a
// root --> leaf_b /> leaf_d
// \> leaf_c --> leaf_e
auto root = std::make_unique<node>();
root->children.emplace_back(std::make_unique<node>(a_data));
root->children.emplace_back(std::make_unique<node>(b_data));
root->children.emplace_back(std::make_unique<node>(c_data));
root->children[2]->children.emplace_back(std::make_unique<node>(d_data));
root->children[2]->children.emplace_back(std::make_unique<node>(e_data));
- 基于节点对。
struct tree
{
std::vector<std::unique_ptr<T>> data = {};
std::vector<std::pair<size_t, size_t>> connections = {};
};
// /> leaf_a
// root --> leaf_b /> leaf_d
// \> leaf_c --> leaf_e
auto boom = tree{};
boom.data.emplace_back(nullptr);
boom.data.emplace_back(a_data);
boom.data.emplace_back(b_data);
boom.data.emplace_back(c_data);
boom.data.emplace_back(d_data);
boom.data.emplace_back(e_data);
boom.connections.emplace_back(std::make_pair(0,1));
boom.connections.emplace_back(std::make_pair(0,2));
boom.connections.emplace_back(std::make_pair(0,3));
boom.connections.emplace_back(std::make_pair(3,4));
boom.connections.emplace_back(std::make_pair(3,5));
当然,这两个例子都可以通过适当的 api 变得更漂亮,但它们只应该展示最基本的实现。
我的问题是: 还有其他方法可以实现树吗?两种方法的优缺点是什么?
注意:我明确需要每个节点有多个子节点的选项,并且每个节点都应该有一个可选的数据字段。
【问题讨论】:
-
就我个人而言,我会将工作外包;)github.com/kpeeters/tree.hh
-
谢谢,我去看看。
-
如果你有一个非常强的假设,即这棵树是一个几乎完全的二叉树,那么你可以方便地将它存储在一个数组中。这就是heaps 通常的实现方式。
-
第三种可能性是让每个子节点指向其父节点(根节点指向 NULL),而不是每个父节点指向其子节点的列表。
-
std::unique_ptr<T>指向子节点不一定是个好主意(销毁时存在堆栈溢出的风险)。std::unique_ptr<T> data = nullptr;是十亿美元的错误。使用T data;并转发构造函数参数。如果您的特定树是指针树,请使用node<std::unique_ptr<whatever>>,但这应该很少见。
标签: c++ data-structures tree