3. C++ STL: deque container

Keywords: C++ Container STL C++11

3.3 deque container

Disclaimer: This article is a note on learning C++ STL - standard template library, which is convenient for later review; Mainly refer to C++ Prime, C + + standard library Dark horse programmer's ingenuity | C + + tutorial: introduction to programming from 0 to 1 Wait.

3.3.1 basic concept of deque container

Function:

  • Double ended array, which can insert and delete the head end, is essentially a dynamic array.

  • Before using deque, the header file #include < deque > must be included;

The difference between deque and vector:

  • vector has low efficiency in inserting and deleting headers. The larger the amount of data, the lower the efficiency;
  • deque can quickly insert and remove elements at both ends, and the insertion and deletion speed of the head is faster than that of the vector;
  • vector accesses elements faster than deque, which is related to their internal implementation;
  • deque does not support capacity and memory reallocation control;
  • The insertion and deletion speed of deque and vector in the middle section is relatively slow.

Internal working principle of deque:

Deque has a central controller to maintain the contents of each buffer. The real data is stored in the buffer. The central controller maintains the address of each buffer, making deque like a continuous memory space

  • The iterator of the deque container also supports random access

3.3.2 deque constructor

Function Description:

  • deque vessel construction

Function prototype:

  • deque<T> deqT; // Default construction form
  • deque(beg, end); // The constructor copies the elements in the [beg, end) interval to itself.
  • deque(n, elem); / / the constructor copies n elems to itself.
  • Deque (const deque & DEQ); / / copy constructor
#include <iostream>
#include <deque>
using namespace std;

void printDeque(const deque<int>& d) 
{
	for (deque<int>::const_iterator it = d.begin(); it != d.end(); it++) {
		cout << *it << " ";

	}
	cout << endl;
}
//deque structure
void test01() {

	deque<int> d1; //non-parameter constructor 
	for (int i = 0; i < 10; i++)
	{
		d1.push_back(i);
	}
	printDeque(d1);
	deque<int> d2(d1.begin(),d1.end());
	printDeque(d2);

	deque<int>d3(10,100);
	printDeque(d3);

	deque<int>d4 = d3;
	printDeque(d4);
}

int main() {

	test01();

	system("pause");

	return 0;
}

Output:

0 1 2 3 4 5 6 7 8 9 
0 1 2 3 4 5 6 7 8 9 
100 100 100 100 100 100 100 100 100 100 
100 100 100 100 100 100 100 100 100 100 

3.3.3 deque assignment

Function Description:

  • Assign a value to the deque container

Function prototype:

  • Deque & operator = (const deque & DEQ); / / overload the equal sign operator
  • assign(beg, end); / / assign the data copy in the [beg, end) interval to itself.
  • assign(n, elem);

Example:

#include <iostream>
#include <deque>
using namespace std;

void printDeque(const deque<int>& d) 
{
	for (deque<int>::const_iterator it = d.begin(); it != d.end(); it++) {
		cout << *it << " ";

	}
	cout << endl;
}
//Assignment operation
void test01()
{
	deque<int> d1;
	for (int i = 0; i < 10; i++)
	{
		d1.push_back(i);
	}
	printDeque(d1);

	deque<int>d2;
	d2 = d1;
	printDeque(d2);

	deque<int>d3;
	d3.assign(d1.begin(), d1.end());
	printDeque(d3);

	deque<int>d4;
	d4.assign(10, 100);
	printDeque(d4);

}

int main() {

	test01();

	system("pause");

	return 0;
}

Conclusion: the deque assignment operation is the same as that of vector, which needs to be mastered

Output:

0 1 2 3 4 5 6 7 8 9 
0 1 2 3 4 5 6 7 8 9 
0 1 2 3 4 5 6 7 8 9 
100 100 100 100 100 100 100 100 100 100 

3.3.4 deque size operation

Function Description:

  • Operate on the size of the deque container

Function prototype:

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

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

  • deque.resize(num); / / re specify the length of the container as num. if the container becomes longer, fill the new location with the default value.

    / / if the container becomes shorter, the element whose end exceeds the length of the container will be deleted.

  • deque.resize(num, elem); / / re specify the length of the container as num. if the container becomes longer, fill the new position with elem value.

    / / if the container becomes shorter, the element whose end exceeds the length of the container will be deleted.

Example:

#include <iostream>
#include <deque>
using namespace std;

void printDeque(const deque<int>& d) 
{
	for (deque<int>::const_iterator it = d.begin(); it != d.end(); it++) {
		cout << *it << " ";

	}
	cout << endl;
}

//Size operation
void test01()
{
	deque<int> d1;
	for (int i = 0; i < 10; i++)
	{
		d1.push_back(i);
	}
	printDeque(d1);

	//Determine whether the container is empty
	if (d1.empty()) {
		cout << "d1 Empty!" << endl;
	}
	else {
		cout << "d1 Not empty!" << endl;
		//Statistical size
		cout << "d1 The size of the is:" << d1.size() << endl;
	}

	//Reassign size
	d1.resize(15, 1);
	printDeque(d1);

	d1.resize(5);
	printDeque(d1);
}

int main() {

	test01();

	system("pause");

	return 0;
}

Output:

0 1 2 3 4 5 6 7 8 9 
d1 Not empty!
d1 Size of: 10
0 1 2 3 4 5 6 7 8 9 1 1 1 1 1 
0 1 2 3 4 

Summary:

  • deque has no concept of capacity
  • Judge whether it is empty - empty()
  • Return the number of elements - size()
  • Reassign number - resize()

3.3.5 deque insertion and deletion

Function Description:

  • Inserting and deleting data into the deque container

Function prototype:

Insert at both ends:

  • push_back(elem); / / add a data at the end of the container
  • push_front(elem); / / insert a data in the container head
  • pop_back(); / / delete the last data in the container
  • pop_front(); / / delete the first data in the container

Specify location operation:

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

  • insert(pos,n,elem); / / insert n elem data at pos without return value.

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

  • clear(); / / clear all data in the container

  • erase(beg,end); / / delete the data in the [beg,end) interval and return the location of the next data.

  • erase(pos); / / delete the data at pos and return the location of the next data.

Example:

#include <deque>

void printDeque(const deque<int>& d) 
{
	for (deque<int>::const_iterator it = d.begin(); it != d.end(); it++) {
		cout << *it << " ";

	}
	cout << endl;
}
//Two end operation
void test01()
{
	deque<int> d;
	//Tail insertion
	d.push_back(10);
	d.push_back(20);
	//Head insert
	d.push_front(100);
	d.push_front(200);

	printDeque(d);

	//Tail deletion
	d.pop_back();
	//Header deletion
	d.pop_front();
	printDeque(d);
}

//insert
void test02()
{
	deque<int> d;
	d.push_back(10);
	d.push_back(20);
	d.push_front(100);
	d.push_front(200);
	printDeque(d);

	d.insert(d.begin(), 1000);
	printDeque(d);

	d.insert(d.begin(), 2,10000);
	printDeque(d);

	deque<int>d2;
	d2.push_back(1);
	d2.push_back(2);
	d2.push_back(3);

	d.insert(d.begin(), d2.begin(), d2.end());
	printDeque(d);

}

//delete
void test03()
{
	deque<int> d;
	d.push_back(10);
	d.push_back(20);
	d.push_front(100);
	d.push_front(200);
	printDeque(d);

	d.erase(d.begin());
	printDeque(d);

	d.erase(d.begin(), d.end());
	d.clear();
	printDeque(d);
}

int main() {

	test01();
	test02();
    test03();
    
	system("pause");

	return 0;
}

Output:

200 100 10 20 
100 10 
200 100 10 20 
1000 200 100 10 20 
10000 10000 1000 200 100 10 20 
1 2 3 10000 10000 1000 200 100 10 20 
200 100 10 20 
100 10 20 

Summary:

  • Insert and delete the provided location is an iterator!
  • push_back
  • Tail delete - pop_back
  • push_front
  • Header deletion - pop_front

3.3.6 deque data access

Function Description:

  • Access to data in deque

Function prototype:

  • at(int idx); / / returns the data indicated by the index idx
  • operator []; / / returns the data indicated by the index idx
  • front(); / / returns the first data element in the container
  • back(); / / returns the last data element in the container

Example:

#include <deque>

void printDeque(const deque<int>& d) 
{
	for (deque<int>::const_iterator it = d.begin(); it != d.end(); it++) {
		cout << *it << " ";

	}
	cout << endl;
}

//data access 
void test01()
{

	deque<int> d;
	d.push_back(10);
	d.push_back(20);
	d.push_front(100);
	d.push_front(200);

	for (int i = 0; i < d.size(); i++) {
		cout << d[i] << " ";
	}
	cout << endl;


	for (int i = 0; i < d.size(); i++) {
		cout << d.at(i) << " ";
	}
	cout << endl;

	cout << "front:" << d.front() << endl;

	cout << "back:" << d.back() << endl;

}

int main() {

	test01();

	system("pause");

	return 0;
}

Output:

200 100 10 20 
200 100 10 20 
front:200
back:20

Summary:

  • In addition to using iterators to get the elements in the deque container, [] and at can also be used
  • front returns the first element of the container
  • back returns the last element of the container

3.3.7 deque sorting

Function Description:

  • Using algorithm to sort deque containers

Algorithm:

  • sort(iterator beg, iterator end) / / sort the elements in the beg and end intervals

Example:

#include <iostream>
#include <deque>
#include <algorithm>
using namespace std;

void printDeque(const deque<int>& d) 
{
	for (deque<int>::const_iterator it = d.begin(); it != d.end(); it++) {
		cout << *it << " ";

	}
	cout << endl;
}

void test01()
{

	deque<int> d;
	d.push_back(10);
	d.push_back(20);
	d.push_front(100);
	d.push_front(200);

	printDeque(d);
	sort(d.begin(), d.end());
	printDeque(d);

}

int main() {

	test01();

	system("pause");

	return 0;
}

Output:

200 100 10 20 
10 20 100 200 

Summary: the sort algorithm is very practical. You can include the header file algorithm when using it

The function of deque is different from vector:

① . deque does not provide capacity operations: capacity() and reserve();

② deque directly provides functions to insert and delete header elements: push_front() and pop_front();

Posted by meritre on Fri, 19 Nov 2021 22:10:43 -0800