C++模板实战5: 迭代器与容器

   容器通过提供大致统一的迭代器界面供外界访问数据,而算法只作用于迭代器,从而摆脱对具体类型的依赖。

   实例1: 带有迭代器的双向链表简易实现:

#include<iostream>
#include<stdexcept>
_Pragma ("once")
template<typename T> class List;
template<typename N>
class Iterator{
    public:
        using value_type=typename N::value_type;
        using reference_type=typename N::reference_type;
        using const_reference_type=typename N::const_reference_type;
        using self_type=Iterator<N>;
        Iterator():pos(0){}
        Iterator(N* p):pos(p){}
        bool operator !=(self_type const& right) const{
            return pos!=right.pos;
        }
        bool operator ==(self_type const& right) const{
            return pos==right.pos;
        }
        self_type& operator++(){
            if(pos){
                pos=pos->next;
            }
            return *this;
        }
        reference_type operator*() throw(std::runtime_error){
            if(pos)
                return pos->value;
            else
                throw (std::runtime_error("defreferenceing null iterator"));
        }
    private:
        N* pos;
        template<typename T> friend class list;
};
template<typename T>
class Node{
    public:
        using value_type=T;
        using reference_type=T&;
        using const_reference_type=const T&;
        T value;
        Node* prev;
        Node* next;
        Node(T const& v,Node* p,Node* n)
            :value(v),prev(p),next(n){}
};
template<typename T>
class List{
    private:
        using node_type=Node<T>;
        node_type* head;
    public:
        using value_type=T;
        using iterator=Iterator<node_type>;
        List():head(nullptr){}
        ~List(){
            while(head){
                node_type* n=head;
                head=head->next;
                delete n;
            }
        }
        void push_front(T const& v){
            head=new node_type(v,nullptr,head);
            if(head->next){
                head->next->prev=head;
            }
        }
        void pop_front(T& v){
            if(head){
                node_type* temp=head;
                head=head->next;
                if(head)
                    head->prev=nullptr;
                v=temp->value;
                delete temp;
            }
        }
        void insert(iterator it,T const& v){
            node_type* n=it.pos;
            if(n){
                node_type* new_node=new node_type(v,n,n->next);
                new_node->next->prev=new_node;
                n->next=new_node;
            }
        }
        void erase(iterator& it){
            node_type* n=it.pos;
            ++it;
            if(n){
                if(n->next)
                    n->next->prev=n->prev;
                if(n->prev)
                    n->prev->next=n->next;
                delete n;
            }
        }
        bool empty() const{
            return head==nullptr;
        }
        iterator begin(){
            return iterator(head);
        }
        iterator end(){
            return iterator();
        }
};
int main(){
    List<int> myList;
    int x=10;
    myList.push_front(x);
    int y;
    myList.pop_front(y);
    std::cout<<myList.empty()<<" "<<y<<std::endl;
    return 0;
}

      实例2:带有迭代器的简易set实现:

#include<stdexcept>
#include<iostream>
using namespace std;
_Pragma("once")
template<typename N>
class Iterator{
    private:
        const N* pos;
    public:
        using value_type=typename N::value_type;
        using const_reference_type=typename N::const_reference_type;
        using self_type=Iterator<N>;
        Iterator():pos(nullptr){}
        Iterator(const N* p):pos(p){}
        bool operator==(self_type const& right) const{
            return pos==right.pos;
        }
        self_type& operator++(){
            if(pos){
                if(pos->right){
                    pos=pos->right;
                    while(pos->left) pos=pos->left;
                }
                else{
                    while((pos->parent)&&(pos->parent->right==pos))
                        pos=pos->parent;
                    pos=pos->parent;
                }
            }
            return *this;
        }
        const_reference_type operator*() const throw(std::runtime_error){
            if(pos) return pos->value;
            else throw std::runtime_error("deferencing null iterator");
        }
};
template<typename N>
bool operator!=(Iterator<N> const &left,Iterator<N> const &right){
    return !(left==right);
}
template<typename T>
class Node{
    public:
        using value_type=T;
        using reference_type=T&;
        using const_reference_type=const T&;
        T value;
        Node* parent;
        Node* left;
        Node* right;
        Node(T const& v,Node* p,Node* l,Node* r)
            :value(v),parent(p),left(l),right(r){}
        ~Node(){
            if(left) delete left;
            if(right) delete right;
        }
};
template<typename T>
class Set{
    private:
        using node_type=Node<T>;
        node_type* root;
    public:
        using value_type=T;
        using const_iterator=Iterator<node_type>;
        Set():root(nullptr){}
        ~Set(){
            if(root)
                delete root;
        }
        bool insert(T const& v){
            node_type** n=&root;
            node_type* p=nullptr;
            while(*n){
                if(v==(*n)->value)
                    return false;
                else{
                    p=*n;
                    n=v<(*n)->value?&((*n)->left):&((*n)->right);
                }
            }
            *n=new node_type(v,p,nullptr,nullptr);
            return true;
        }
        bool has(T const& v){
            node_type* n=root;
            while(n){
                if(v==n->value)
                    return true;
                n=v<n->value?n->left:n->right;
            }
            return false;
        }
        bool empty() const{
            return root==nullptr;
        }
        const_iterator begin(){
            node_type* n=root;
            while(n->left) n=n->left;
            return const_iterator(n);
        }
        const_iterator end() const{
            return const_iterator();
        }
};
int main(){
    Set<int> mySet;
    int x=10;
    mySet.insert(x);
    cout<<mySet.has(int(10))<<" "<<mySet.empty()<<endl;
    return 0;
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
C++ std::map迭代器是用来遍历map容器中的元素的工具。迭代器可以指向map容器中的每个键值对,允许访问键和值。在C++中,有三种常用的迭代器类型:基础迭代器、反向迭代器和常量迭代器。 基础迭代器是通过`begin()`和`end()`函数来获取的。`begin()`函数返回指向map容器中第一个元素的迭代器,而`end()`函数返回指向map容器中最后一个元素之后位置的迭代器。基础迭代器可以使用自增运算符`++`来遍历map容器中的键值对,并通过解引用(*)操作符来获得键和值。例如,使用`map<string, int>::iterator`类型定义迭代器,并通过循环遍历map容器中的键值对,可以实现对map容器的遍历。 反向迭代器是通过`rbegin()`和`rend()`函数来获取的。`rbegin()`函数返回指向map容器中最后一个元素的迭代器,而`rend()`函数返回指向map容器中第一个元素之前位置的迭代器。反向迭代器可以使用自减运算符`--`来遍历map容器中的键值对,并通过解引用(*)操作符来获得键和值。反向迭代器可以实现对map容器的反向遍历。 常量迭代器是通过`cbegin()`和`cend()`函数来获取的。常量迭代器与基础迭代器类似,但是不能修改map容器中的元素。常量迭代器可以用于在不改变map容器的情况下遍历元素。 综上所述,C++ std::map迭代器是用于遍历map容器中的键值对的工具。基础迭代器、反向迭代器和常量迭代器分别用于正向遍历、反向遍历和只读遍历map容器。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [C++ std::map用迭代器遍历删除遇到的坑](https://blog.csdn.net/zidian666/article/details/125673395)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *2* *3* [C++map迭代器最全最容易理解](https://blog.csdn.net/qq_53547805/article/details/122146122)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值