【问题标题】:Binary Search Tree using std::unique ptr使用 std::unique_ptr 的二叉搜索树
【发布时间】:2021-12-27 11:36:53
【问题描述】:

我正在尝试使用智能指针实现二叉搜索树,并且我已经阅读了实现它的推荐方法是使用 unique_ptr,因为父母拥有孩子,并且二叉搜索树中没有多个所有者。

以这棵树为例,

                       10
            4                      20       
      2           5          11          30
         3

这里 4 是 10 的左孩子,2 是 4 的左孩子,3 是 2 的右孩子,依此类推。

现在结构看起来像,

template<typename T>
struct TreeNode {
    T data;
    std::unique_ptr<TreeNode<T>> left, right; 
};

有一个unique_ptr&lt;TreeNode&lt;T&gt;&gt; root 指向根。

现在,如果我理解正确,unique_ptr's 不能被复制或分配,并且他们拥有该对象的唯一所有权。

因此,如果我想遍历树,我无法执行诸如将 std::unique_ptr&lt;TreeNode&lt;T&gt;&gt; temp 初始化为根并从那里遍历每个节点的操作,因为一旦我尝试设置 root 即会抛出错误unique_ptrtemp

那么我需要使用TreeNode* 类型的原始指针来遍历树并执行操作吗?这样做是好的还是安全的?对于我在这棵树上的所有操作,我是否必须使用原始指针?

另一个问题是删除节点。如果我说要删除值为3 的节点。如果我初始化TreeNode* temp 类型的原始指针并到达Treenode 3。那么如果我调用 delete(temp) 会发生什么?来自TreeNode 2unique_ptr 指向TreeNode 3。这个指针会发生什么?

【问题讨论】:

  • 如果我打电话给delete(temp) 会发生什么 - 未定义的行为。
  • TreeNode* 可用于遍历树(只要您不将该指针用于其所有者(转移或删除))。
  • @Evg 仅当持有它的unique_ptr 被访问或销毁时
  • 使用原始指针没有错,智能指针负责所有权,如果您只使用智能指针作为所有权,那么在您的代码中很清楚任何原始指针都不拥有指向的对象
  • "如果我说要删除节点" 您应该只需要像left = nullptr;root = nullptr; 这样的代码来删除节点(及其子节点)。没有delete 可写。 root = std::move(root-&gt;left); 之类的代码也可能有用。

标签: c++ pointers binary-search-tree smart-pointers unique-ptr


【解决方案1】:

那么如果我调用 delete(temp) 会发生什么?

TreeNode 将被销毁。注意delete 不需要括号

来自TreeNode 2 的unique_ptr 指向TreeNode 3。这个指针会发生什么?

指针变得无效,unique_ptr 对象被销毁是未定义的行为,因为它将尝试 delete 无效指针。

那么我是否需要使用 TreeNode* 类型的原始指针来遍历树并执行操作?这样做是好的还是安全的?对于我在这棵树上的所有操作,我是否必须使用原始指针?

你可以有一个std::unique_ptr的引用(或指针),你不需要复制它。

您可以调用unique_ptrreset 成员函数来释放指向的TreeNode,而不是delete 一个原始指针

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-10-17
    • 2023-03-08
    • 1970-01-01
    • 2020-05-24
    • 1970-01-01
    • 2010-10-26
    相关资源
    最近更新 更多