[C++]迭代器实现及二维链表实现


最近因为期末所以好久没更新了,最近会把一些积累的存货发出来
这章主要讲的是迭代器,那么什么是迭代器呢?
这篇文章各位可以和之前我发的二维链表实现对照起来看

我们知道,尽管不同容器的内部结构各异,但它们本质上都是用来存储大量数据的,换句话说,都是一串能存储多个数据的存储单元。因此,诸如数据的排序、查找、求和等需要对数据进行遍历的操作方法应该是类似的。
既然类似,完全可以利用泛型技术,将它们设计成适用所有容器的通用算法,从而将容器和算法分离开。但实现此目的需要有一个类似中介的装置,它除了要具有对容器进行遍历读写数据的能力之外,还要能对外隐藏容器的内部差异,从而以统一的界面向算法传送数据。
这是泛型思维发展的必然结果,于是迭代器就产生了。
REFERENCE:http://c.biancheng.net/view/6675.html跳转

迭代器的种类

迭代器有很多种:正迭代器、逆迭代器、随机访问迭代器、双向迭代器等等
它们支持 ++p,p++,*p 操作,还可以被复制或赋值,可以用 == 和 != 运算符进行比较
正向迭代器就是最常见的形式,可以通过++移动到下一个元素,反向迭代器则相反,双向迭代器顾名思义支持前进和后退操作,值得一提的是,这里前进代表移动到下一个元素,而后退意味着移动到前一个元素
随机访问迭代器功能更加强大,支持前后移动i个单位元素
下面以我的作业为例展示迭代器的实现方法

.hpp文件

我们需要将实现写在doubll2d-impl.hpp中,我不知道为什么这么include不会报错,哪位懂的老哥可以在评论区介绍一下

#ifndef _HW7_DOUBLL2D_HPP_
#define _HW7_DOUBLL2D_HPP_

#include <cstddef>
#include <iterator>
#include <functional>

template<typename T>
class doubll2d;

// Detailed implementation of doubll2d.
// Namespaces are used to prevent users from directly using them.
namespace __detail {
   
// Helper class for creating iterable from two iterators.
// You do not need to implement or use this.
template<typename T>
class iterable {
   
private:
    T begin_;
    T end_;

public:
    iterable(T begin, T end) : begin_{
   begin}, end_{
   end} {
   }

    T begin() const {
    return begin_; }

    T end() const {
    return end_; }
};

template<typename T>
iterable<T> make_iterable(T begin, T end) {
    return iterable<T>{
   begin, end}; }

// Helper class to create reverse iterator from normal iterator.
// You do not need to implement or use this.
template<class I>
class reverse_iter
        : public std::iterator<typename std::iterator_traits<I>::iterator_category,
                typename std::iterator_traits<I>::value_type,
                typename std::iterator_traits<I>::difference_type,
                typename std::iterator_traits<I>::pointer,
                typename std::iterator_traits<I>::reference> {
   
public:
    explicit reverse_iter(I iter) : inner{
   iter} {
   }

    // reference operator (implemented)
    typename reverse_iter::reference operator*() {
    return *inner; }

    // pointer operator (implemented)
    typename reverse_iter::pointer operator->() {
    return &*inner; }

    // self increment operator (implemented)
    reverse_iter &operator++() {
   
        --inner;
        return *this;
    }

    reverse_iter operator++(int) {
    return reverse_iter{
   inner--}; }

    // self decrement operator (implemented)
    reverse_iter &operator--() {
   
        ++inner;
        return *this;
    }

    reverse_iter operator--(int) {
    return reverse_iter{
   inner++}; }

    // comparison operator (implemented)
    bool operator==(const reverse_iter &other) {
    return inner == other.inner; }

    bool operator!=(const reverse_iter &other) {
    return inner != other.inner; }

private:
    I inner;
};

// List node, you do not need to implement this
template<typename T>
class list_node {
   
public:
    // Initialize the node with a value (implemented)
    explicit list_node(const T &value) :
            left{
   nullptr}, right{
   nullptr}, up{
   nullptr}, down{
   nullptr}, data{
   value} {
   }

    // Copy constructor (compiler generated)
    list_node(const list_node &other) = default;

    // Destructor (compiler generated)
    ~list_node() = default;

    // Copy assignment operator (compiler generated)
    list_node &operator=(const list_node &rhs) = default;

    // adjacent nodes
    list_node *left;
    list_node *right;
    list_node *up;
    list_node *down;

    // Data of the node
    T data;
};

// Iterator of the list element in some row.
template<typename T>
class list_row_elem_iter : public std::iterator<std::bidirectional_iterator_tag, T> {
   
public:
    explicit list_row_elem_iter(list_node<T> *inner) : inner{
   inner} {
   }

    // reference operator (implement this)
    typename list_row_elem_iter::reference operator*();

    // pointer operator (implement this)
    typename list_row_elem_iter::pointer operator->();

    // self increment operator (implement this)
    // move to the right element
    list_row_elem_iter &operator++();

    list_row_elem_iter operator++(int);

    // self decrement operator (implement this)
    // move to the left element
    list_row_elem_iter &operator--();

    list_row_elem_iter operator--(int);

    // comparison operator (implement this)
    bool operator==(const list_row_elem_iter &other);

    bool operator!=(const list_row_elem_iter &other);

private:
    list_node<T> *inner;

    // this allows you get the inner node inside this iter
    friend class doubll2d<T>;
};

// Iterator of the row in the list
template<typename T>
class list_row_iter : public std::iterator<std::bidirectional_iterator_tag, list_row_iter<T>> {
   
public:
    // Type renaming
    using iterator = list_row_elem_iter<T>;
    using reverse_iterator = __detail::reverse_iter<iterator>;

    list_row_iter(list_node<T> *left, list_node<T> *right) : left{
   left}, right{
   right} {
   }

    // the leftmost iterator of this row (implement this)
    iterator begin();

    // the iterator next to the rightmost element in this row (implement this)
    iterator end();

    // the `reverse_iterator` of the rightmost element in this row (implement this)
    reverse_iterator rbegin();

    // the `reverse_iterator` before the leftmost element in this row (implement this)
    reverse_iterator rend();

    iterable<reverse_iterator> riterable() {
    return make_iterable(rbegin(), rend()); }

    // reference operator (implement this)
    typename list_row_iter::reference operator*();

    // pointer operator (implement this)
    typename list_row_iter::pointer operator->();

    // self increment operator (implement this)
    // move to the row below
    list_row_iter &operator++();

    list_row_iter operator++(int);

    // self decrement operator (implement this)
    // move to the row above
    list_row_iter &operator--();

    list_row_iter operator--(int);

    // comparison operator (implement this)
    bool operator==(const list_row_iter &other);

    bool operator!=(const list_row_iter &other);

private:
    list_node<T> *left;        // leftmost element in the row
    list_node<T> *right;       // rightmost element in the row
};

// Iterator of the list element in some column.
template<typename T>
class list_col_elem_iter : public std::iterator<std::bidirectional_iterator_tag, T> {
   
public:
    // Type renaming
    explicit list_col_elem_iter(list_node<T> *inner) : inner{
   inner} {
   }

    // reference operator (implement this)
    typename list_col_elem_iter::reference operator*();

    // pointer operator (implement this)
    typename list_col_elem_iter::pointer operator->();

    // self increment operator (implement this)
    // move to the element below
    list_col_elem_iter &operator++();

    list_col_elem_iter operator++(int);

    // self decrement operator (implement this)
    // move to the element above
    list_col_elem_iter &operator--();

    list_col_elem_iter operator--(int);

    // comparison operator (implement this)
    bool operator==(const list_col_elem_iter &other);

    bool operator!=(const list_col_elem_iter &other);

private:
    list_node<T> *inner;

    // this allows you get the inner node inside this iter
    friend class doubll2d<T>;
};

// Iterator of the column in the list
template<typename T>
class list_col_iter : public std::iterator<std::bidirectional_iterator_tag, list_col_iter<T>> {
   
public:
    // Type renaming
    using iterator = list_col_elem_iter<T>;
    using reverse_iterator = __detail::reverse_iter<iterator>;

    list_col_iter(list_node<T> *up, list_node<T> *down) : up{
   up}, down{
   down} {
   }

    // the top iterator of this column (implement this)
    iterator begin();

    // the iterator below the bottom element in this column (implement this)
    iterator end();

    // the `reverse_iterator` of the bottom element in this column (implement this)
    reverse_iterator rbegin();

    // the `reverse_iterator` above the top element in this column (implement this)
    reverse_iterator rend();

    iterable<reverse_iterator> riterable() {
    return make_iterable(rbegin(), rend()); }

    // reference operator (implement this)
    typename list_col_iter::reference operator*();

    // pointer operator (implement this)
    typename list_col_iter::pointer operator->();

    // self increment operator (implement this)
    // move to the next column
    list_col_iter &operator++();

    list_col_iter operator++(int);

    // self decrement operator (implement this)
    // move to the previous column
    list_col_iter &operator--();

    list_col_iter operator--(int);

    // comparison operator (implement this)
    bool operator==(const list_col_iter &other);

    bool operator!=(const list_col_iter &other);

private:
    list_node<T> *up;        // top element in the column
    list_node<T> *down;      // bottom element in the column
};
}

// 2D Doubly linked list class
template<typename T>
class doubll2d {
   
public:
    // Type renaming
    using size_type = size_t;
    using row_iter = __detail::list_row_iter<T>;
    using col_iter = __detail::list_col_iter<T>;
    using row_riter = __detail::reverse_iter<row_iter>;
    using col_riter = __detail::reverse_iter<col_iter>;

    // Default constructor
    doubll2d() :
            up_left{
   nullptr}, up_right{
   nullptr},
            down_left{
   nullptr}, down_right{
   nullptr},
            dim_row{
   0}, dim_col{
   0} {
   }

    // Copy and move constructor are deleted
    doubll2d(const doubll2d &other) = delete;

    doubll2d(doubll2d &&other) = delete;

    // Destructor
    ~doubll2d() {
    clear(); }

    // Copy and move assignment operator are deleted
    doubll2d &operator=(const doubll2d &other) = delete;

    doubll2d &operator=(doubll2d &&other) = delete;

    // The number of rows in the list
    size_type get_dim_row() const {
    return dim_row; }

    // The number of columns in the list
    size_type get_dim_col() const {
    return dim_col; }

    // Iterator to the first (top) row (implement this)
    row_iter row_begin();

    // Iterator below the last (bottom) row (implement this)
    row_iter row_end();

    __detail::iterable<row_iter> row_iterable() {
   
        return __detail::make_iterable(row_begin(), row_end());
    }

    // `reverse_iterator` to the last (bottom) row (implement this)
    row_riter row_rbegin();

    // `reverse_iterator` above the first (top) row (implement this)
    row_riter row_rend();

    __detail::iterable<row_riter> row_riterable() {
   
        return __detail::make_iterable(row_rbegin(), row_rend());
    }

    // Iterator to the first (leftmost) column (implement this)
    col_iter col_begin();

    // Iterator after the last (rightmost) column (implement this)
    col_iter col_end();

    __detail::iterable<col_iter> col_iterable() {
   
        return __detail::make_iterable(col_begin(), col_end());
    }

    // `reverse_iterator` to the last (rightmost) column (implement this)
    col_riter col_rbegin();

    // `reverse_iterator` before the first (leftmost) column (implement this)
    col_riter col_rend();

    __detail::iterable<col_riter> col_riterable() {
   
        return __detail::make_iterable(col_rbegin(), col_rend());
    }

    // Insert a new row in the list below the row referenced by `cursor`.
    // The data stores from `input_iter` `begin` to `end`. (implement this)
    //
    // Remember, our 2D doubly linked list should always be a rectangular. When the length
    // of data is shorter than it should be, you should fill the rest part by default value of T.
    // Additionally, it is okay that the length of data is longer than needed, in this case
    // you should make use of the `dim_col` items from `begin` and ignore the extra elements.
    //
    // If the list is empty, you should insert the whole data from `begin` to `end`.
    // If the list is empty and `begin` equals to `end`, do nothing and return `row_end()`.
    //
    // If the cursor equals to `row_end()` operator, insert the data above the origin first row.
    //
    // Return the iter of the row inserted.
    template<typename input_iter>
    row_iter insert_row(row_iter cursor, input_iter begin, input_iter end);

    // Insert a new column in the list after the column referenced by `cursor`.
    // The data stores from `input_iter` `begin` to `end`. (implement this)
    //
 
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值