STL_deque container

1. Introduction to deque

Deque is the abbreviation of "double-ended queue". It is an STL container like vector. Deque is a double-ended array, while vector is single-ended.

The interface of deque is very similar to vector, and it can be directly replaced in many operations.

Deque can access elements randomly (support index value direct access, using [] operator or at() method).

**Deque head and tail add or remove elements very quickly. **But it takes time to insert or remove elements in the middle.

#include <deque>

principle:

Deque container is a continuous space, at least logically, the continuous current space always reminds us of array and vector. Array cannot grow. Although vector can grow, it can only grow towards the end, and its growth is actually a Fake, in fact (1) apply for more space (2) copy the new space of the original data (3) release the original space in three steps, if it is not for the vector to leave room every time a new space is allocated, the cost of the growth illusion it's very expensive.

Deque is composed of sections of quantitative continuous space. Once it is necessary to add a new space at the front or end of the deque, configure a continuous quantitative space and connect it in series at the head or end of the deque. Deque's biggest job is to maintain the illusion of the integrity of these segmented continuous memory spaces and provide random access interfaces, avoiding the reconfiguration of space, copying, and releasing the cycle, at the cost of a complex iterator architecture.

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

Deque takes a so-called map (note that it is not the STL map container) as the master control. The so-called map here is a small continuous memory space, in which each element (here becomes a node) is a pointer to Another continuous memory space is called a buffer. The buffer is the main body of the deque storage space.

Difference with vector:

The biggest difference between the deque container and the vector container is that deque allows the use of constant item time to insert and delete elements at the head end. The second is that deque does not have the concept of capacity, because it is dynamically combined with segmented continuous spaces. A new space can be added and linked at any time. In other words, like a vector, "the old space is insufficient and a new piece of space is reconfigured. Large space, then copy the elements, and then release the old space" such a thing will not happen to deque. Therefore, deque does not have to provide the so-called reserve function.

Although the deque container also provides Random Access Iterator, its iterator is not an ordinary pointer, and its complexity is not the same as the vector, which of course affects the level of various operations. Therefore, unless necessary, we should use vector instead of deque as much as possible . For the sorting operation of deque, for the highest efficiency, the deque can be completely copied to a vector, the vector container is sorted, and then copied back to the deque .

Second, the structure of the deque object

deque is implemented using template classes, and the default structure of the deque object: deque<T> deqT;

  • deque <int> deqInt; //A deque container for storing int.

  • deque <float> deqFloat; //A deque container for floats.

  • deque<string> deqString; //A deque container for storing strings.

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

deque(beg, end);//The constructor copies the elements in the [beg, end) range to itself.

deque(n, elem);//The constructor copies n elems to itself.

deque(const deque &deq);//copy constructor.

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

Three, add and remove operations at the end of deque

deque.push_back(elem); //Add a data to 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<int> 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}

Four, deque data access

deque.at(idx); //Return the data pointed to by index idx, if idx is out of range, throw out_of_range.

deque[idx]; //Return the data pointed to by the index idx. If idx is out of range, no exception will be thrown and an error will occur directly.

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

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

	deque<int> 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

Five, 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 first element from the bottom in the container.

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

	deque<int> deqInt;

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

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

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

Six, deque assignment

deque.assign(beg,end); //Assign a copy of the data in the interval [beg, end) to itself. Note that the interval is left closed and right opened.

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

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

deque.swap(deq); // swap vec with its own elements

	deque<int> 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);                      //互换

Seven, the size of the deque

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

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

deque.resize(num); //Re-specify the length of the container as num. If the container becomes longer, the new position will be filled with the default value. If the container becomes shorter, the elements at the end that exceed the length of the container are deleted.

deque.resize(num, elem); //Re-specify the length of the container as num. If the container becomes longer, fill the new position with the elem value. If the container becomes shorter, the elements at the end that exceed the length of the container are deleted.

	deque<int> 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
    }

Eight, the insertion of deque

deque.insert(pos,elem); //Insert a copy of the element element at the pos position and return the position of the new data.

deque.insert(pos,n,elem); //Insert n elem data at position pos, no return value.

deque.insert(pos,beg,end); //Insert the data in the [beg,end) interval at the pos position, no return value.

	deque<int> deqA;
    deque<int> 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}

Nine, the deletion of deque

deque.clear(); //Remove all data of the container

deque.erase(beg,end); //Delete the data in the [beg,end) interval and return the position of the next data.

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

	//删除区间内的元素

	//deqInt是用deque<int>声明的容器,现已包含按顺序的1,3,5,6,9元素。
	deque<int>::iterator itBegin=deqInt.begin()+1;
	deque<int>::iterator itEnd=deqInt.begin()+3;
	deqInt.erase(itBegin,itEnd);
	//此时容器deqInt包含按顺序的1,6,9三个元素。 

	//假设 deqInt 包含1,3,2,3,3,3,4,3,5,3,删除容器中等于3的元素
	for(deque<int>::iterator it=deqInt.being(); it!=deqInt.end(); )  {
    
    
        //小括号里不需写 ++it	
		if(*it == 3){
    
    
			it = deqInt.erase(it);    
            //以迭代器为参数,删除元素3,并把数据删除后的下一个元素位置返回给迭代器。
		    //此时,不执行 ++it; 
		}
		else{
    
    
		    ++it;
		}
	}
 
//删除deqInt的所有元素
deqInt.clear();         //容器为空

Guess you like

Origin blog.csdn.net/weixin_45341339/article/details/113092870