[C ++]-vector, queue, list of STL container

1. STL classification

c ++ STL is also called standard template libaray standard template library.
Listed below are common to our C ++ STL container
Insert picture description here
Insert picture description here
Insert picture description here
vessel configuration destructor, releasing the object open memory space is arranged by the vessel allocator implemented
allocate memory opens responsible
dealocate responsible for releasing the memory
construct object construction
destory the object destruct

Second, vector

1. The underlying data structure
dynamically developed array, each time the capacity of vector vec is expanded by twice the original space size;
2. The relevant interface is
Insert picture description here
increased:
vec.push_back (20); add elements at the end of the container, O (1) causes the container to expand
vec.insert (it, 20); Add an element 20 O (n) at the position pointed to by the iterator, causing the container to expand

Delete:
vec.pop_back (); delete the element O (1) at the end
vec.erase (it); delete the element O (n) pointed to by the iterator
Note: continuous insertion or deletion of the container (insert / erase) must be Update the iterator, otherwise the first insert or erase is completed, the iterator is invalid

Example 1: Realize to delete all even numbers in vec container

int main()
{
vector<int> vec;
auto it2 = vec.begin();
	while (it2 != vec.end())
	{
		if (*it2 % 2 == 0)
		{

			it2 = vec.erase(it2);
		}
		else
		{
			++it2;
		}
	}
	return 0;
}

If it is just vec.erase (it2); the iterator will be invalid after execution, it2 can not be added. Therefore, the iterator needs to be updated once, and after deletion, the following elements are moved to the position of the current iterator, so it2 ++ is not used.
In addition, the current element continues to judge. If the current element is not even, the iterator ++
operation results are as follows:
Insert picture description here
Example 2: Add an even number less than odd 1 to all odd numbers in the vector container (continuous insertion)

int main()
{
vector<int> vec;
auto it1 = vec.begin();
	for (it1 = vec.begin(); it1 != vec.end(); ++it1)
	{
		if (*it1 % 2 != 0)
		{
			it1=vec.insert(it1, *it1 - 1);//要对迭代器进行更新
			it1++;
		}
	}
	return 0;
}

To update the iterator. Find the odd number and perform two ++ operations, as shown in the figure below, find 47 and insert 46 before it, ++ it1 insert 46, it1 should also ++ update the iterator to find The next odd number.Insert picture description here

Query:
operator []; because the bottom layer is an array, the biggest feature of the array is to randomly access the vec [5] O (1)
iterator iterator to
find through the array subscript , for_each
foreach => through iterator to achieve

3. The common method
size (): returns the valid data element at the bottom of the container
empty (): judges whether the container is empty
reserve (20): reserves space for the vector only opens the specified size of memory space for the bottom of the container, and does not add new Element
resize (20): container expansion not only opens up a memory space of a specified size to the bottom of the container, but also adds a new element
swap: two containers exchange elements

Here, we have to make a special distinction between reserve and resize.
The reserve is mainly to reserve space for the vector container, the following code verification:

int main()
{
	vector<int> vec;//默认开辟的vector,底层空间为0
	vec.reserve(20);

	cout << vec.empty() << endl;//输出布尔值
	cout << vec.size() << endl;
	
	for (int i = 0; i < 20; i++)
	{
		vec.push_back(rand() % 100 + 1);
	}
	cout << vec.empty() << endl;
	cout << vec.size() << endl;
	return 0;
}

The running result is as follows:
Insert picture description here
so we can see that reserve reserves space for the vector container 20 but there is no data in it, so empty is true, and the addition process will not cause an increase in capacity. So in the end it was still 20 capacity.

Resize is the container expansion, the following code verification

int main()
{
	vector<int> vec;//默认开辟的vector,底层空间为0
	vec.resize(20);

	cout << vec.empty() << endl;//输出布尔值
	cout << vec.size() << endl;
	
	for (int i = 0; i < 20; i++)
	{
		vec.push_back(rand() % 100 + 1);
	}
	cout << vec.empty() << endl;
	cout << vec.size() << endl;
	return 0;
}

The results of the operation are as follows:
Insert picture description here
not only 20 spaces are opened, but 20 plastic elements with 0 are stored in it, and the expansion starts when 20 additional elements are
added, so empty is false. The addition process adds another 20 elements. So the final output
is 40.4. Traversing the vector container through the iterator
Method 1:

auto it1 = vec.begin();
	for (; it1 != vec.end(); ++it1)
	{
		cout << *it1 << " ";
	}

Method 2:

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

Three, queue and list

1. Double-ended queue container queue

1. The underlying data structure

Dynamically developed two-dimensional array, one-bit array starts from 2 and expands by 2 times. After each expansion, the original second-dimensional array is stored starting from the subscript oldsize / 2 of the new first-dimensional array The same blank line is reserved to facilitate the addition of deque deq to the first and last elements of deque;
as shown below, when a queue is full, then a queue is expanded downward.
Insert picture description here
When both queues are full, then expand
Insert picture description here
2. Related interfaces are
Insert picture description here
added:
deq.push_back (20); add element O (1) from the end
deq.push_front (20); add element O (1) //vec.insert(vec.begin(),20) O (n)
deq. insert (it, 20); add element O (n) where it points

Delete:
deq.pop_back (); delete element O (1) from the end deq.pop_front (); delete element O (1)
from the header
deq.erase (it); delete element O (n) from the position it points to

Query search:
iterator (continuous insert and erase must consider the problem of iterator failure)

2. List of linked list containers

1. The underlying data structure The
bidirectional circular linked list pre data next, as shown in the figure:
Insert picture description here
2. Related interfaces are
Insert picture description here
added:
mylist.push_back (20); add elements from the end O (1)
mylist.push_front (20); add elements from the head O (1) //vec.insert(vec.begin(),20) O (n)
mylist.insert (it, 20); Add the element at the position it points to O (1) When inserting in the linked list, you must first Perform a query query operation
For linked lists, the query operation efficiency is relatively slow

Delete:
mylist.pop_back (); delete element O (1) from the end
mylist.pop_front (); delete element O (1)
mylist.erase (it) from the head; delete element O (n) from the position it points to

Query search:
iterator (continuous insert and erase must consider the problem of iterator failure)

Deque and list more than the vector container, add and delete function interfaces:
push_front and pop_fornt

Four, the difference between vector, queue and list

1. The difference between vector and deque

Vector features: Dynamically developed arrays , the memory is continuous, and the capacity is expanded by 2 times vector vec;

Deque features: dynamically developed two-dimensional array space , deque bottom memory is not continuous, the second dimension is a fixed-length array space, when expanding (double expansion of the first dimension array)
1, the difference between the underlying data structure
2 3. The time complexity of inserting elements before, after,
middle and at the end is the same as O (1). Inserting deque in front is O (1) because the double-ended queue can be expanded before or after, but vectorO (n)

3. For the efficiency
of memory use , the memory space required by the vector must be continuous, and the deque can be divided into blocks for data storage. The memory space does not need to be continuous.

4. Insert or erase in the middle, the efficiency vector is better, and deque is worse.
Although the time complexity is O (n), it is necessary to consider the convenience of movement. Since the second-dimensional memory space of deque is not continuous, insert or erase of the element in the middle of the deque causes the element to move slower than the vector.
As shown in the following figure:
Insert picture description here
In deque, each second dimension is continuous (renewed), which is a piecewise continuous.
An element is deleted, and the movement of the following elements must first be found in one dimension, the address of the starting position is stored, and then the element movement position is found according to the offset.
However, the deletion of vector is very simple, as shown in the following figure:
Insert picture description here
Because his storage space is continuous, it can be moved one by one in sequence.

2. The difference between vector and list

The difference between these two is similar to the difference between an array and a linked list, such an association makes it easy to get the answer

1. The underlying data structure
One is a dynamic array and the other is a doubly circular linked list

2. Add, delete and modify the time complexity

Array increase delete O (n) query O (n) random access O (1)
linked list consider search time The rest of the delete query time complexity is O (1)

Published 98 original articles · won praise 9 · views 3659

Guess you like

Origin blog.csdn.net/qq_43412060/article/details/105266945