What data structure, exactly, are deques in C++?

后端 未结 7 897
我寻月下人不归
我寻月下人不归 2020-12-04 19:44

Is there a specific data structure that a deque in the C++ STL is supposed to implement, or is a deque just this vague notion of an array growable from both the front and th

相关标签:
7条回答
  • 2020-12-04 20:19

    The datas in deque are stored by chuncks of fixed size vector, which are

    pointered by a map(which is also a chunk of vector, but its size may change)

    The main part code of the deque iterator is as below:

    /*
    buff_size is the length of the chunk
    */
    template <class T, size_t buff_size>
    struct __deque_iterator{
        typedef __deque_iterator<T, buff_size>              iterator;
        typedef T**                                         map_pointer;
    
        // pointer to the chunk
        T* cur;       
        T* first;     // the begin of the chunk
        T* last;      // the end of the chunk
    
        //because the pointer may skip to other chunk
        //so this pointer to the map
        map_pointer node;    // pointer to the map
    }
    

    The main part code of the deque is as below:

    /*
    buff_size is the length of the chunk
    */
    template<typename T, size_t buff_size = 0>
    class deque{
        public:
            typedef T              value_type;
            typedef T&            reference;
            typedef T*            pointer;
            typedef __deque_iterator<T, buff_size> iterator;
    
            typedef size_t        size_type;
            typedef ptrdiff_t     difference_type;
    
        protected:
            typedef pointer*      map_pointer;
    
            // allocate memory for the chunk 
            typedef allocator<value_type> dataAllocator;
    
            // allocate memory for map 
            typedef allocator<pointer>    mapAllocator;
    
        private:
            //data members
    
            iterator start;
            iterator finish;
    
            map_pointer map;
            size_type   map_size;
    }
    

    Below i will give you the core code of deque, mainly about two parts:

    1. iterator

    2. Simple function about deque

    1. iterator(__deque_iterator)

    The main problem of iterator is, when ++, -- iterator, it may skip to other chunk(if it pointer to edge of chunk). For example, there are three data chunks: chunk 1,chunk 2,chunk 3.

    The pointer1 pointers to the begin of chunk 2, when operator --pointer it will pointer to the end of chunk 1, so as to the pointer2.

    Below I will give the main function of __deque_iterator:

    Firstly, skip to any chunk:

    void set_node(map_pointer new_node){
        node = new_node;
        first = *new_node;
        last = first + chunk_size();
    }
    

    Note that, the chunk_size() function which compute the chunk size, you can think of it returns 8 for simplify here.

    operator* get the data in the chunk

    reference operator*()const{
        return *cur;
    }
    

    operator++, --

    // prefix forms of increment

    self& operator++(){
        ++cur;
        if (cur == last){      //if it reach the end of the chunk
            set_node(node + 1);//skip to the next chunk
            cur = first;
        }
        return *this;
    }
    
    // postfix forms of increment
    self operator++(int){
        self tmp = *this;
        ++*this;//invoke prefix ++
        return tmp;
    }
    self& operator--(){
        if(cur == first){      // if it pointer to the begin of the chunk
            set_node(node - 1);//skip to the prev chunk
            cur = last;
        }
        --cur;
        return *this;
    }
    
    self operator--(int){
        self tmp = *this;
        --*this;
        return tmp;
    }
    

    2. Simple function about deque

    common function of deque

    iterator begin(){return start;}
    iterator end(){return finish;}
    
    reference front(){
        //invoke __deque_iterator operator*
        // return start's member *cur
        return *start;
    }
    
    reference back(){
        // cna't use *finish
        iterator tmp = finish;
        --tmp; 
        return *tmp; //return finish's  *cur
    }
    
    reference operator[](size_type n){
        //random access, use __deque_iterator operator[]
        return start[n];
    }
    

    If you want to understand deque more deeply you can also see this question https://stackoverflow.com/a/50959796/6329006

    0 讨论(0)
提交回复
热议问题