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;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值