zoukankan      html  css  js  c++  java
  • list源码1(参考STL源码--侯捷):list节点、迭代器、数据结构

    list源码1(参考STL源码--侯捷):list节点、迭代器、数据结构

    list源码2(参考STL源码--侯捷):constructor、push_back、insert

    list源码3(参考STL源码--侯捷):push_front、push_back、erase、pop_front、pop_back、clear、remove、unique

    list源码4(参考STL源码--侯捷):transfer、splice、merge、reverse、sort

    list概述

    list相对于vector复杂得多,list是一个双链表,对于插入元素、删除元素,list都相对比较简单

    list节点

    template <class T>
    struct __list_node{
        typedef void* void_pointer;
        void_pointer prev; //类型为void*,其实也可以设置为__list_node<T>*
        void_pointer next;
        T data;
    };

    list迭代器

    list迭代器必须有能力指向list的节点,并有能力进行正确的递增、递减、取值、成员存取等操作,同时list是双向链表,迭代器必须具备前移、后移的能力,所以list提供的是Bidirectional Iterators。

    list有一个重要性质:插入(insert)操作和接合(splice)操作都不会造成原有的list迭代器失效,甚至list的元素删除(erase)操作也只有“指向被删除元素”的那个迭代器失效,其它迭代器失效不受任何影响。

    template<class T,class Ref,class Ptr>
    struct __list_iterator{
        typedef __list_iterator<T,T&,T*> iterator;
        typedef __list_iterator<T,Ref,Ptr> self;
        
        typedef bidirectional_iterator_tag iterator_category;
        typedef T value_type;
        typedef Ptr pointer;
        typedef Ref reference;
        typedef __list_node<T>* link_type;
        typedef size_t size_type;
        typedef ptrdiff_t difference_type;
        
        link_type node; //迭代器内部需要一个普通指针,指向list的节点
        
        //constructor
        __list_iterator(link_type x):node(x){}
        __list_iterator(){}
        __list_iterator(const iterator& x):node(x.node){}
        
        bool operator ==(const self& x)const{return node==x.node;}
        bool operator !=(const self& x)const{return node!=x.node;}
        
        //以下对迭代器取值,取的是节点的数据值
        reference operator->() const{return &(operator*());}
        
        //对迭代器累加
        self& operator++(){
            node=(link_type)((*node).next);
            return *this;
        }
        self operator++(int){
            self tmp=*this;
            ++*this;
            return tmp;
        }
        
        //对迭代器减1
        self& operator--(){
            node=(link_type)((*node).prev);
            return *this;
        }
        self operator--(int){
            self tmp=*this;
            --*this;
            return tmp;
        }
    };

    list数据结构

    list不仅是一个双向链表,而且还是一个环状双向链表,所以它只需要便可以完整表现整个链表:

    template <class T,class Alloc=alloc> //缺省使用alloc为适配器
        class list{
        protected:
            typedef __list_node<T> list_node;
        public:
            typedef list_node* link_type;
            
        protected:
            link_type node; //只要一个指针,便可表示整个环装双向链表
            ......
        };

    如果让node(如上)指向刻意置于尾端的一个空间节点,node便能符合STL对于“前闭后开”区间的要求,成为last迭代器,如下图,这样以来,以下几个函数可以很好完成:

    iterator begin(){return (link_type)((*node).next);}
    iterator end(){return node;}
    bool empty() const{return node->next==node;}
    size_type size() const{
        size_type result=0;
        distance(begin(),end(),result);
        return result;
    }
    //取头结点的内容
    reference front(){return *begin();}
    //取尾节点的内容
    reference back(){return *(--end());}

     

  • 相关阅读:
    菜鸟学习Spring Web MVC之二
    菜鸟学习Spring Web MVC之一
    Internet Explorer 6 的15个讨厌的bug和简单的解决方法
    前端遇到的跨域问题及解决方案二
    前端遇到的跨域问题及解决方案一
    第六 添加文字
    第五章、使用预绘制图片
    第四、渐变和图案
    第三 画曲线
    第二、画线和路径
  • 原文地址:https://www.cnblogs.com/ybf-yyj/p/9843391.html
Copyright © 2011-2022 走看看