Ten minutes to take you familiar with the serialization container of STL

The so-called serialized container means that the elements in it can be ordered, but not necessarily ordered . The C++ language itself provides a serialization container array, and STL also provides serialization containers such as vector, list, deque, stack, queue, priority-queue, etc. Among them , stack and queue are all modified deques, and are technically classified as adapters.

array

Internal Maintenance : Continuous Linear Space

Static space : If the memory space is insufficient, the programmer needs to control and apply for a larger space, move the data in the old space and the newly added data to the new space, and then release the old space. Apply for new space - data movement - release old space

vector

The data structure of vector :

  • Internal Maintenance : Continuous Linear Space

  • Dynamic space, automatic expansion.

  • Expansion mechanism : apply for new space—data movement—release old space. Generally, the new space applied for is twice the old space. If the new space still cannot load all the data, apply for a larger space.

    • Because capacity expansion is not carried out behind the original space, because there may not be enough space behind the original space for expansion, so once the capacity is expanded, the iterator of the old space will become invalid, so we must pay attention
  • vector element operations

    • Insertion: It is very convenient to insert at the end of the vector, but it will be more complicated if it is inserted at the non-end, because the elements after the insertion position need to be moved backward one by one
    • Deletion: Similar to insertion, deletion at the end is very simple. Deleting non-ends requires moving the elements after the deletion position forward one by one
    • Search: Can iterate to any position through iterator increment and decrement, operator+, operator-
    • Modification: By finding any position, you need to use the dereference character (*) to access the data at this position, such as: iter = 0, if iter points to the first position of the space at this time, then iter is the same as iter[0]. The first element is modified to 0

vector iterators:

  • Ordinary pointers can be used as vector iterators and satisfy all necessary conditions.

    • Because the operation behaviors required by vector iterators, such as operator*, operator->, operator+, operator-, operator++, operator–, operator+=, operator-=, are inherently available for ordinary pointers, vector supports random storage, and pointers can also be satisfied.
  • Vector maintains three iterators: start, finish, end_of_storage

    • start: the beginning of the configured continuous space
    • finish: the used end of the configured contiguous space
    • end_of_storage: the end of the configured continuous space

Common APIs

	// 创建一个int类型的Vector数组
	// 并对数组进行初始化,其中长度为5、元素为4
	vector<int> nums(5, 4);
	// 向队尾插入元素10
	nums.push_back(10);
	// 向队尾插入元素15
	nums.push_back(15);
	// 插入元素2到nums.begin()迭代器之前
	nums.insert(nums.begin(), 2); 
	// 查询数组找到第一个元素为10的位置,返回其迭代器
	vector<int>::iterator it = find(nums.begin(), nums.end(), 10);
	if (it != nums.end())
		nums.insert(it, 7);
	nums.insert(nums.end(), 99);
	// 删除最后一位元素
	nums.pop_back();
	// 删除迭代器指向的元素
	nums.erase(nums.begin() + 1); 
	
	for (int i : nums)
		cout << i << " ";

Please add a picture description

list

list data type

  • Internal maintenance: circular doubly linked list
// 节点
tmplate <class T>
struct _list_node{
    
    
  typedef void* void_pointer;
  void_pointer prev;
  void_pointer next;
  T data;
}

// List
template <class T, class Alloc = alloc> // 缺省使用alloc为配置器
class List{
    
    
protected:
    typedef _list_node<T> list_node;
public:
    typedef list_node* link_type;
protected:
    link_type node; // 只要一个指针,便可表示整个环状双向链表
}
  • list element operation
    • As long as the pointer node is deliberately pointed to a blank node at the end, the insertion and deletion operations at the beginning and end are the same, and both insertion and deletion operations are O(1)

list iterator

  • Custom data type - bidirectional iterator , need to provide the correct increment, decrement, value, member reference of the iterator
    • Increment: point to the next node
    • Decrement: point to the previous node
    • Value: Take out the data value of the node
    • Member reference: access to the members of the node
  • Iterator invalidation:
    insertion and splicing will not invalidate the original list iterator;
    deletion will only invalidate the iterator pointing to the deleted element
  • Point the pointer node to a blank node deliberately placed at the end, the next node of node is the first of the linked list, and the previous node of node is the last of the linked list , then node can meet the interval requirements of STL before closing and then opening , and become a list iterator

slist

slist data type

  • Internal maintenance: circular one-way linked list
  • According to the habit of STL, the insertion operation generally inserts new elements before the specified position, not after. However, for a one-way linked list, if it needs to be inserted before the specified position, it needs to be traversed again, so for the area near the starting point of the slist , It is very unwise to use insert and erase. For this, slist specially provides insert_after() and erase_after() for flexible use
  • Also for the sake of efficiency, slist only provides push_back(), not push_front(), so the order of elements will be opposite to the order of insertion

therefore

deque data type

  • Internal maintenance: Segmented continuous space. Deque contains a map inside ( the map here is not the map container of STL, but a small continuous space ) as the main control, and the elements (here called node nodes) are all pointers , pointing to the continuous space at the other end, called cache area . The cache area is the main storage space of the deque .

  • Deque is a continuous linear space with two-way openings (at least in terms of logic, it is actually a piecewise continuous space internally), and the speed of inserting and deleting elements is constant no matter from which position

    Vector is a continuous linear space with one-way openings . Although elements can be inserted and deleted from the beginning, the efficiency is extremely poor.

  • Deque avoids applying for new space - data movement - releasing old space , at the cost of complex iterator architecture

deque iterator

  • Because deque internally maintains a piecewise continuous space, in order to maintain its "overall continuous" illusion, the heavy responsibility falls on operator++ and operator-

    • First of all, the iterator needs to be able to judge whether it is on the edge of the buffer area. If it is, it needs to jump to the next or previous edge of the buffer area to move forward or backward. In order to be able to jump accurately, it is necessary to always grasp the map (main control)
  • In addition to maintaining a pointer to the map, the iterator also maintains two iterators: start, finish

    • start: points to the first element of the first buffer
    • end: point to the next position of the last element of the last buffer

stack

  • The stack is a first-in, last-out data structure with only one exit. It only needs to provide top insertion, top deletion, and top element acquisition. Except for the top, there is no other way to store other elements of the stack, and there is no need for traversal behavior, so stack has no iterators

  • By default, the stack uses deque as the bottom structure , that is, the stack maintains a deque to complete all the work, and all the stack needs to do is to seal the head of the deque and only provide operations on the tail (the top of the stack).

    • "Modify the interface of something to form another style" - known as an adapter , stack is an adapter, so STL stack is often not classified as a container, but is classified as a container adapter
  • The list can also be used as the bottom structure of the stack . As a data structure with two-way openings, the list also provides empty, size, back, push_back, and pop_back. You only need to close the head end of the list to form a stack very easily.

queue

  • Queue is a first-in-first-out data structure, which can only take out data from the head of the queue and insert data from the end of the queue. In addition, there are no other methods of accessing elements, and no traversal behavior is required. There is no iterator

  • The bottom structure is exactly the same as the stack, but the processing interface of the bottom structure is different to achieve different styles

heap

  • heap is not an STL container component, but a behind-the-scenes hero, acting as an assistant to priority_queue .

  • Internal maintenance: a vector array, a heap algorithm

    • vector array: used to store elements
    • heap algorithm: maintain a complete binary tree internally
      • According to the element arrangement method, heap can be divided into max-heap and min-heap
        • max-heap: the key value of each node is larger than the child node
        • min-heap: the key value of each node is smaller than the child node
        • STL provides max-heap, so the following algorithm uses max-heap by default
      • push_heap algorithm:
        • Condition: Two iterators: used to represent the head and tail of the heap's underlying container (vector)
        • Algorithm steps:
          • The newly added element must be placed at the bottom, and placed in the first space from left to right, that is, at the end() of the bottom vector
          • Uptracking: compare the key value of the new node with the parent node. If the key value is greater than the parent node, the parent and child swap positions, and so on, until there is no need to swap or until the root node (the parent and child positions in the vector must also need to be corrected) change position)
      • pop_heap algorithm:
        • Condition: Two iterators: used to represent the head and tail of the heap's underlying container (vector)
        • Prophetic condition: For max-heap, the maximum value must be at the root of the heap, that is, at the first position of the vector. After the pop operation, the lowest rightmost leaf node must be discarded
        • Algorithm steps:
          • First, swap the first and last elements of the vector, that is, swap the root node of the heap with the rightmost leaf node at the bottom
          • Descent: compare the key value adjusted to the root node with the child node, if it is smaller than the child node, swap it with the larger child node, and so on until there is no need to swap or reach the bottom
        • Note: After each execution of the pop_heap algorithm, the largest element is only placed at the end of the bottom container and has not been taken out. It can be obtained through the back() of the bottom container. If you want to remove it, use the pop_back() of the bottom container function
      • sort_heap algorithm:
        • Prophetic condition: Every time the pop_heap algorithm is executed, the element with the largest key value will be obtained, but the maximum value is not cleared, but placed at the end of the underlying container
        • Algorithm core: always call the pop_heap algorithm, reduce the operation range by one element from the back to the front each time (put the largest element at the end of the bottom container), when the entire program is executed, the elements in the bottom container will change into an increasing sequence
      • make_heap algorithm: used to convert a piece of existing data into a heap
        • Algorithm idea: Because there is no node loophole in the whole tree of a complete binary tree, for a node at any position i, the position of its left child node must be 2i, and the position of its right child node must be 2i+1
  • heap has no iterators

priority_queue

  • priority_queue is completely based on the underlying container (vector), plus heap processing rules, and finally modify the interface on the basis of these, and finally provide unique rules, which is an adapter
  • The rules of priority_queue: the one with the highest weight goes out first
  • You only need to insert data from the end of the queue and get data from the head of the queue. There are no other methods to operate on elements in other positions, and there is no need for traversal functions, so there is no iterator

Guess you like

Origin blog.csdn.net/weixin_44081533/article/details/119509362