STL_ Deque container

Time:2021-4-21

1、 About deque

Deque is the abbreviation of “double ended queue”. Like vector, deque is a container of STL. Deque is a double ended array, while vector is a single ended array.

Deque is very similar to vector in interface, and can be directly replaced in many operations.

Deque can access elements randomly (direct access to index values is supported, using the [] operator or at () method).

Both the head and tail of deque add or remove elements very quickly.However, it is time-consuming to insert or remove elements in the middle.

include

Principle:

Deque container is a continuous space, at least logically. Continuous space always reminds us of array and vector, Array can’t grow. Although vector can grow, it can only grow to the end. In fact, its growth is an illusion. In fact, (1) applying for more space, (2) copying the original data into a new space, and (3) releasing the original space, there are three steps. If vector doesn’t have enough space every time it configures a new space, the cost of its growth illusion is very expensive.

Deque is composed of quantitative continuous space. Once it is necessary to add new space at the front end or tail end of deque, a continuous quantitative space is configured and connected in series at the head end or tail end of deque. Deque’s biggest job is to maintain the illusion of integrity of these segmented and continuous memory space, and provide random access interface, avoiding the cycle of space reconfiguration, replication and release, at the cost of complex iterator architecture.

Since deque is a segmented continuous memory space, there must be a central control to maintain the illusion of overall continuity. The design of data structure and the forward and backward operation of iterator are rather cumbersome.Deque code is much more implemented than vector or list

Deque takes a so-called map ( Note that it is not a map container for STL ) As the master, the so-called map here is a small continuous memory space, in which each element ( This becomes a node ) Is a pointer to another continuous memory space, called a buffer. The buffer is the main body of deque’s storage space.

The difference between vector and vector is as follows

One of the biggest differences between deque container and vector container is that deque allows constant term time to insert and delete elements from the header. The second is that deque has no concept of capacity, because it is a dynamic combination of segmented and continuous spaces, and a new space can be added and linked at any time. In other words, like vector, such things as “when the old space is insufficient, reconfigure a larger space, then copy the elements, and then release the old space” will not happen to deque. Therefore, deque does not have to provide the so-called space reservation ( reserve ) Function.

Although deque container also provides random access iterator, its iterator is not an ordinary pointer, and its complexity and vector are not of the same order of magnitude, which of course affects the level of each operation. Therefore, unless necessary,We should use vector instead of deque as much as possibleTo sort deque, for the highest efficiency, you can copy deque completely to a vector, sort the vector container, and then copy it back to deque

2、 Construction of deque object

Deque is implemented by template class, and the default construction form of deque object is deque deqT;

  • deque Deqint; / / a deque container for int.

  • deque deqFloat ; // A deque container for float.

  • dequeDeqstring; / / a deque container for strings.

  • //You can also set pointer type or custom type in angle brackets.

deque ( beg , end );// The constructor will [ beg , end ) The elements in the interval are copied to itself.

Deque (n, elem); / / the constructor copies n elems to itself.

Deque (const deque & DEQ); / / copy the constructor.

deque d1;
	deque d2(10, 5);
	deque d3(d2.begin(), d2.end());
	deque d4(d3);

3、 Add remove operation at the end of deque

deque.push_ Back (elem); / / add a data at the end of the container

deque.push_ Front (elem); / / insert a data in the container head

deque.pop_ Back(); / / delete the last data of the container

deque.pop_ Front(); / / delete the first data of the container

deque deqInt;

    deqInt.push_back(1);
    deqInt.push_back(3);
    deqInt.push_back(5);
    deqInt.push_back(7);

    deqInt.pop_front();
    deqInt.pop_front();

    deqInt.push_front(11);
    deqInt.push_front(13);

    deqInt.pop_back();

//deqInt { 13,11,5}

4、 Data access of deque

deque.at (IDX); / / returns the data indicated by index idx. If IDX goes beyond the bounds, it throws out_ of_ range。

Deque [IDX]; / / returns the data indicated by index idx. If IDX goes beyond the boundary, no exception will be thrown and an error will be made directly.

deque.front (); / / returns the first data.

deque.back (); / / returns the last data

deque deqInt;
 
 	deqInt.push_back(1);
    deqInt.push_back(3);
    deqInt.push_back(5);
    deqInt.push_back(7);
    deqInt.push_back(9);

	int iA = deqInt.at(0);        //1
    int iB = deqInt[1];           //3
    deqInt.at(0) = 99;           //99
    deqInt[1] = 88;         //88
    int iFront = deqInt.front();    //99
    int iBack = deqInt.back();    //9
    deqInt.front() = 77;         //77
    deqInt.back() = 66;         //66

5、 Deque and iterator

deque.begin (); / / returns the iterator of the first element in the container.

deque.end (); / / returns the iterator after the last element in the container.

deque . rbegin (); // Returns the iterator of the penultimate element in the container.

deque.rend (); / / returns the iterator after the last element in the container.

deque deqInt;

    deqInt.push_back(1);
    deqInt.push_back(3);
	deqInt.push_back(5);
    deqInt.push_back(7);
    deqInt.push_back(9);

    for (deque::iterator it=deqInt.begin(); it!=deqInt.end(); ++it)
    {
         cout << *it;
         cout << "";
     }
    // 1 3 5 7 9

	for (deque::reverse_iterator rit=deqInt.rbegin(); rit!=deqInt.rend(); ++rit)
    {
	     cout << *rit;
         cout << "";
    }
    //9 7 5 3 1

6、 Assignment of deque

deque . assign ( beg , end ); // take [ beg , end ) The data copy in the interval is assigned to itself. Note that the interval is left closed and right open.

deque.assign (n, elem); / / assign n elem copies to itself.

deque & operator =( const deque & deq ); // Overloading the equal sign operator

deque.swap (DEQ); / / swap VEC with its own elements

deque deqIntA,deqIntB,deqIntC,deqIntD;

    deqIntA.push_back(1);
    deqIntA.push_back(3);
    deqIntA.push_back(5);
	deqIntA.push_back(7);
    deqIntA.push_back(9);

    deqIntB.assign(deqIntA.begin(),deqIntA.end());   // 1 3 5 7 9
   
    deqIntC.assign(5,8);                         //8 8 8 8 8

    deqIntD = deqIntA;                          //1 3 5 7 9

	deqIntC.swap (deqintd); // interchange

7、 The size of deque

deque.size (); / / returns the number of elements in the container

deque.empty (); / / judge whether the container is empty

deque . resize ( num ); // Re specify the length of the container to num. if the container becomes longer, the new position will be filled with the default value. If the container becomes shorter, the element whose end exceeds the length of the container is removed.

deque.resize (Num, elem); / / re specify the length of the container to num. if the container becomes longer, fill in the new position with the value of elem. If the container becomes shorter, the element whose end exceeds the length of the container is removed.

deque deqIntA;

	deqIntA.push_back(1);
    deqIntA.push_back(3);
    deqIntA.push_back(5);

    int iSize = deqIntA.size(); //3

	if (!deqIntA.empty())
    {
        deqIntA.resize(5);      //1 3 5 0 0
        deqIntA.resize(7,1); 	//1 3 5 0 0 1 1
        deqIntA.resize(2);      //1 3
    }

8、 Insertion of deque

deque . insert ( pos , elem ); // Insert a copy of the elem element in the POS position to return the location of the new data.

deque.insert (POS, N, elem); / / insert n elem data at POS, no return value.

deque.insert (POS, beg, end); / / insert the data in the [beg, end] interval at the POS position, and there is no return value.

deque deqA;
    deque deqB;

    deqA.push_back(1);
	deqA.push_back(3);
    deqA.push_back(5);
	deqA.push_back(7);
    deqA.push_back(9);

	deqB.push_back(2);
    deqB.push_back(4);
    deqB.push_back(6);
    deqB.push_back(8);
   
    deqA.insert(deqA.begin(), 11);        //{11, 1, 3, 5, 7, 9}
    deqA.insert(deqA.begin()+1,2,33);     //{11,33,33,1,3,5,7,9}
    deqA.insert(deqA.begin() , deqB.begin() , deqB.end() ); //{2,4,6,8,11,33,33,1,3,5,7,9}

9、 Deletion of deque

deque.clear (); / / remove all data from the container

deque . erase ( beg , end ); // delete [ beg , end ) Interval data, return the position of the next data.

deque . erase ( pos ); // Delete the data in POS position and return to the position of the next data.

//Delete the elements in the interval

	//Deqint is a container declared with deque and now contains elements 1, 3, 5, 6, 9 in order.
	deque::iterator itBegin=deqInt.begin()+1;
	deque::iterator itEnd=deqInt.begin()+3;
	deqInt.erase(itBegin,itEnd);
	// At this point, the deqint container contains 1 in order , six , 9 three elements. 

	//Suppose deqint contains 1,3,2,3,3,3,4,3,5,3, and delete the element equal to 3 in the container
	for(deque::iterator it=deqInt.being(); it!=deqInt.end(); )  {
        //There is no need to write + + it in parentheses	
		if(*it == 3){
			it = deqInt.erase(it);    
            //Taking the iterator as a parameter, delete element 3 and return the position of the next element after data deletion to the iterator.
		    //At this time, + + it is not executed; 
		}
		else{
		    ++it;
		}
	}
 
//Delete all elements of deqint
deqInt . clear ();         // The container is empty