【问题标题】:The proper way to increment my binary tree增加二叉树的正确方法
【发布时间】:2021-05-06 16:39:42
【问题描述】:

这是我创建的类

#include <memory>

template <typename T> 
class binary_tree {

private:
    T t_data;
    std::unique_ptr<binary_tree<T>> t_left, t_right;
    
    class binary_tree_iterator {                  // -----------------------
    private:
        T data;
    public:                                       
        binary_tree_iterator(T d) : data(d) {}    //     Iterator class
        T& operator*() {return data;}
        binary_tree_iterator& operator++() {} // <--------- ??????
    };                                            
                                                  // ------------------------
public:
    binary_tree(T d) : t_data(d), t_left(nullptr), t_right(nullptr)
    {}
    
    void insert(T data) {
        if(data <= t_data) {
            if(t_left == nullptr) {
                t_left = std::unique_ptr<binary_tree<T>>(new binary_tree<T>(data));
            } else {
                t_left->insert(data);
            }          
        } else {
            if(t_right == nullptr)
                t_right = std::unique_ptr<binary_tree<T>>(new binary_tree<T>(data));
            else
                t_right->insert(data);
        }
    }
    
    const T data() const {
        return t_data;
    }
    
    const std::unique_ptr<binary_tree<T>>& left() const {
        return t_left;
    }
    
    const std::unique_ptr<binary_tree<T>>& right() const {
        return t_right;
    }
    
    binary_tree_iterator begin() {      
        if(t_left == nullptr) {
            return binary_tree_iterator(t_data);
        } else {
            return t_left->begin();
        }
    }
    
    binary_tree_iterator end() {
        if(t_right == nullptr) {
            return binary_tree_iterator(t_data);
        } else {
            return t_right->end();
        }
    }
};

我已经在我的容器类中声明了我的迭代器类。这可能是一个错误,但无论哪种方式,我都不确定如何定义我的重载增量函数。一旦我找到了 begin() 我就迷路了。似乎 unique_ptr() 是为单向指向而设计的。假设我必须以这种方式使用 unique_ptr,这里有一些工作吗?我曾考虑为 binary_tree 的每个实例提供一个头成员,该成员指向它的来源,但每个节点只能从其上方的节点访问。我做了某种索引,但这似乎完全违背了这种容器类型的目的。我正在解决练习,所以我只能使用 unique_ptr。

【问题讨论】:

  • unique_ptr 用于内存管理,而不是用于组织树。尝试使用普通指针!
  • 使用 unique_ptr 表示具有 unique_ptr 的类“拥有”指向的对象,并负责删除它。这对于树节点对其子节点持有的指针(有些)有意义,对于您需要的父指针没有意义,因为子节点不拥有它的父节点(而是相反)。只需为此目的使用原始指针。
  • @U.W. unique_ptr 非常适合树中的子指针
  • @john 我需要 left() 和 right() 成员返回 unique_ptr ¯_(ツ)_/¯
  • @Joemoor94 现在这确实没有意义。如果您有名为 left()right() 的 getter 方法返回一个唯一指针,那么这意味着它们正在转移左子或右子的所有权(这没有意义),或者它们正在分配一个新的子节点并返回一个唯一的指向它的指针(这也没有意义)。

标签: c++ class c++11 iterator unique-ptr


【解决方案1】:

您将迭代器定义为在树中包含 data 值。

这不是迭代器的全部意义所在。迭代器不包含它们所引用的值,而是对它的引用(在这个词的一般含义中,而不是 C++ 术语中),通常是一个指针。

当然你不知道如何处理++。对于您的迭代器,很自然地期望 ++ 运算符将迭代器推进到树中的下一个节点,但是由于迭代器不包含指向任何东西的指针,所以您没有什么可推进的,并遇到精神障碍。

您需要重新设计您的迭代器,使其包含指向您的binary_tree 的指针;它的* 重载取消引用; ++ 前进到二叉树中的下一个元素,然后它可以使用它的指针来执行此操作。

此时你会遇到另一个心理障碍。遍历整个二叉树有时需要备份到树中的父节点。毕竟,在递归到二叉树的left 部分之后,在某个时候,在遍历二叉树之后,您将需要以某种方式以某种方式结束二叉树的right 部分。但是,按照设计,您的 binary_tree 无法导航到任何节点的父节点。这是您需要以某种方式解决的另一个设计缺陷。

我想,有可能在迭代器本身中实现整个回溯,让迭代器记录它访问的每个节点,以便在需要时备份到它。但是迭代器应该是轻量级的对象,它们本身只是一个指针,而不是实现复杂操作的成熟数据结构。

总之,您需要解决二叉树设计中的几个漏洞,然后才能为其实现有效的迭代器。

【讨论】:

  • 你在告诉我
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-07-14
  • 2011-08-30
  • 1970-01-01
  • 2019-10-28
  • 1970-01-01
  • 1970-01-01
  • 2016-01-09
相关资源
最近更新 更多