微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

C,为二叉树实现自定义迭代器(长)

请你好 – 这是我的第一个问题. = P

基本上作为夏季项目,我一直在浏览wikipedia page上的数据结构列表并尝试实现它们.我上学期参加了一门C课程并发现它非常有趣,作为我实施二项式堆的最后一个项目 – 这也非常有趣.也许我很讨厌,但我喜欢数据结构.

无论如何,足够的背景故事.项目进展顺利,我从二叉树开始.为了更进一步,我需要创建迭代器来遍历树.我已经决定为每个遍历方法(常规迭代器和常量迭代器)创建两种类型的迭代器,我只是不知道如何做到这一点.我听说从stl的迭代器继承,甚至使用boosts iterator_facade(这似乎是个不错的选择)

我还没有尝试编写迭代器代码,因为我不知道从哪里开始,但我确实在github上有我当前的代码.你可以看看here.

如果你反对github,我会粘贴相关的类定义.这些功能的实现实际上没有任何帮助,但如果您出于某种原因需要它们,请告诉我.此外,节点类具有用于迭代目的的父指针.

#ifndef __TREES_HXX
#define __TREES_HXX
#include <cstdlib>  // For NULL
#include <algorithm> // for std::max

// Node class deFinition. These nodes are to be used for any
// tree where the structure is
//    node
//     /\
// left  right
//  /\    /\
//
// etc.,basically two children.
template <typename T>
class Node
{
  public:
    T data_;
    Node<T>* left_;
    Node<T>* right_;
    Node<T>* parent_; // Needed for iterators

    explicit Node(T const&);
    Node(Node<T> const&);
};

template <typename T>
class BinaryTree
{
  protected:
    typedef Node<T>* node_t;
    size_t tree_size;

  public:
    typedef T value_type;

    explicit BinaryTree();
    explicit BinaryTree(T const&);
    ~BinaryTree();

    virtual node_t insert(node_t&,T) = 0;
    virtual T& lookup(node_t const&,T const&) const = 0;
    inline virtual size_t size() const;
    inline virtual size_t depth(node_t const&) const;
    inline bool empty() const;
    inline void clear(node_t);

    node_t root;
};

这是我们抽象类的基本二叉树扩展,基本上它(将是)一个BST.有关我需要迭代器的原因的示例,请查看查找函数的定义.它应该将迭代器返回到找到东西的节点.

/* Implementation of our Binary Tree is in
 * this file. The node class is in Trees.hxx
 * because it's intended to be a general class.
 */

 #ifndef __BINARY_TREE_HXX
 #define __BINARY_TREE_HXX

 #include "Trees.hxx"


 template <typename T>
 class BiTree : public BinaryTree<T>
 {
   private:
     typedef typename BinaryTree<T>::node_t node_t;

   public:
     typedef typename BinaryTree<T>::value_type value_type;

     BiTree() : BinaryTree<T>()
     {
     }

     BiTree(T const& data) : BinaryTree<T>(data)
     {
     }

     node_t insert(node_t&,T);
     T& lookup(node_t const&,T const&) const; // Note: This should return an iterator to the node where the stuff is found
 };

我想就是这样 – 谢谢你的时间!如果您需要其他信息,请告诉我们.

解决方法

1.胖迭代器与精益迭代器

有两种可能的方法来实现树的遍历.你可以:

>有节点只是指向他们的“子”,以及保持堆栈的迭代器(因此,胖迭代器)
>让节点具有父指针(就像你的那样),迭代器只是指向给定节点的指针(精益迭代器)

这是一个设计权衡,STL实现者通常采用精益方式,因为迭代器(在STL中)应该是便宜的复制.

2. Easy Iterators vs From scratch迭代器

还有几种方法可以实现迭代器:

> From Scratch:你自己做所有事情,包括定义typedef,所有运算符重载等等……
>简单:您使用Boost.Iterator自己实现尽可能少的代码

我基本上将从std :: iterator继承为“从头开始”的情况,因为它只提供了5个typedef …

是否选择其中一个确实取决于您的情况:

>出于学习目的,我建议多次使用“From Scratch”方式
>出于生产目的,我建议采用“From Scratch”方式(从Boost继承并不节省太多,但它确实使调试会话/内存转储复杂化,至少使用gdb,因为gdb暴露了基类)
>为了快速测试,我建议采用“简单”方式

请注意,您可能处于一个奇怪的情况,您的迭代器无法真正构建在Boost.Iterator之上,在这种情况下,您将别无选择,只能自己构建它.

3. Const和非const迭代器

这也许是重点.

如果仅为此,则值得查看Boost.Iterator,因为它们公开了实现一个迭代器(模板化)的技术,它将涵盖两种情况.

查看Iterator Adaptor中的Tutorial Example部分:

template <class Value>
class node_iter
  : public boost::iterator_adaptor<
        node_iter<Value>                // Derived,Value*                          // Base,boost::use_default              // Value,boost::forward_traversal_tag    // CategoryOrTraversal
    >
{
 private:
    struct enabler {};  // a private type avoids misuse

 public:
    node_iter()
      : node_iter::iterator_adaptor_(0) {}

    explicit node_iter(Value* p)
      : node_iter::iterator_adaptor_(p) {}

    /// !!! Highlight !!!
    template <class OtherValue>
    node_iter(
        node_iter<OtherValue> const& other,typename boost::enable_if<
            boost::is_convertible<OtherValue*,Value*>,enabler
        >::type = enabler()
    )
      : node_iter::iterator_adaptor_(other.base()) {}

 private:
    friend class boost::iterator_core_access;
    void increment() { this->base_reference() = this->base()->next(); }
};

第三个构造函数获取一对const和非const迭代器的关键点,它们可以自动从const转换为非const,而不需要进行反向转换.

无论你做什么,重用同样的技巧:在Value上模拟BaseIterator,并提供两个typedef:typedef BaseIterator< Value> iterator和typedef BaseIterator< Value const>常量性.

原文地址:https://www.jb51.cc/c/119023.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐