如何初始化嵌套结构的unique_ptr(例如二叉树)
How to initialize unique_ptr of nested structs (e.g. for binary trees)
在现代c++中,通常建议在处理二叉树时使用unique_ptr
来明确子树的所有权。例如,编程面试元素建议:
template <typename T>
struct Node {
T data;
unique_ptr<Node<T>> left, right;
};
我正在学习c++ 11的特性,我想知道什么是最方便的方法来初始化一个二叉树对应于一个特定的结构。我的用例是为特定的树编写单元测试。例如,我想生成这样的树:
5
/
3 4
/
1 2
下面的代码可以工作,但是非常麻烦:
// first attempt: temporary variables & high syntactic noise
unique_ptr<Node<int>> tmp_n1(new Node<int>{1, nullptr, nullptr});
unique_ptr<Node<int>> tmp_n2(new Node<int>{2, nullptr, nullptr});
unique_ptr<Node<int>> tmp_n3(new Node<int>{3, move(tmp_n1), move(tmp_n2)});
unique_ptr<Node<int>> tmp_n4(new Node<int>{4, nullptr, nullptr});
unique_ptr<Node<int>> root(new Node<int>{5, move(tmp_n3), move(tmp_n4)});
我希望实现的是摆脱临时变量,并在一个嵌套语句中初始化树。如果代码结构类似于树结构就好了。但是,下面的尝试失败,出现"could not convert"错误:
// second attempt: nested, but still a lot of syntax noise
unique_ptr<Node<int>> root(new Node<int>{5,
new unique_ptr<Node<int>>(new Node<int>{3,
new unique_ptr<Node<int>>(new Node<int>{1, nullptr, nullptr}),
new unique_ptr<Node<int>>(new Node<int>{2, nullptr, nullptr})
}),
new unique_ptr<Node<int>>(new Node<int>{4, nullptr, nullptr})
});
有任何想法如何写这样的树初始化在一个语法干净,简洁,灵活的方式?
这是一个使用c++ 14 make_unique
的解决方案,左子树和右子树的默认参数设置为nullptr
,以避免原始的new
:
#include <iostream>
#include <memory>
template<class T>
struct Node;
template<class T>
using node_ptr = std::unique_ptr<Node<T>>;
template<class T>
struct Node
{
T data;
node_ptr<T> left, right;
Node(T const& value, node_ptr<T> lhs, node_ptr<T> rhs)
:
data(value), left(std::move(lhs)), right(std::move(rhs))
{}
};
template<class T>
auto make_node(T const& value, node_ptr<T> lhs = nullptr, node_ptr<T> rhs = nullptr)
{
return std::make_unique<Node<T>>(value, std::move(lhs), std::move(rhs));
}
template<class T>
void print_tree(Node<T> const& node)
{
std::cout << "{ ";
std::cout << node.data;
if (node.left) {
std::cout << ", ";
print_tree(*(node.left));
}
if (node.right) {
std::cout << ", ";
print_tree(*(node.right));
}
std::cout << " }";
}
int main()
{
auto const root = make_node(
5,
make_node(
3,
make_node(1),
make_node(2)
),
make_node(4)
);
print_tree(*root);
}
实际示例也打印树。
Update:由于@Jarod42的评论,我将print_tree
的签名更改为Node<T> const&
,因此它现在是const-correct,您不必在任何地方键入.get()
。我还制作了一个模板别名 node_ptr<T>
,以便在实现中为unique_ptr<Node<T>>
提供更简洁的符号。
感谢@Satus的评论,我能够想出一些(现在正在工作)辅助功能:
template <typename T>
unique_ptr<Node<T>> new_node(const T& data,
unique_ptr<Node<T>> left = nullptr,
unique_ptr<Node<T>> right = nullptr) {
return unique_ptr<Node<int>>(new Node<int>{data, move(left), move(right)});
}
允许这样构造一个树:
auto root =
new_node(5,
new_node(3,
new_node(1),
new_node(2)),
new_node(4)
);
我仍然不确定这是否是一个更有经验的c++ 11程序员会做的,但对我来说,这是朝着正确方向迈出的一步。
相关文章:
- 从父数组测试用例构造二叉树失败
- 打印时有二叉树问题.用户输入不打印任何内容
- 试图找到二叉树的深度
- 二叉树结构平衡,使用递归时EXC_BAD_ACCESS
- 指向二叉树中新节点的指针
- 我试图用这段代码找到二叉树的高度,但它一直返回 0,有人可以告诉我为什么吗?
- C++:如何计算二叉树中其值模块高度小于 2 的节点数?
- 二叉树级别顺序遍历在leetcode中
- 运行无限循环的最小二叉树问题
- 打印二叉树中的常见元素
- 二叉树基准测试结果
- 带有矢量重复值的二叉树打印出来
- 签入二叉树的函数是平衡C++
- 我有两棵二叉树.我想在不更改输入树的情况下深度复制两个二叉树的结果
- 如何计算给定数字在二叉树中出现的次数?
- 为什么我的二叉树会覆盖其根的叶子?
- 将二叉树的节点插入链表 (C++)
- 二叉树级别顺序插入 c++
- 在 C++ 中创建两个不同的二叉树时出现分段错误
- 如何在使用 ItemType 的模板类时将新节点插入二叉树 c++.(我是 c++ 的新手)