Container in C++ (STL container)

definition

Container: Template classes and function libraries that can manipulate a variety of data structures and algorithms. Various types of objects can be stored like containers in reality, and all objects in a container must be of the same type.

Containers are divided into two categories: sequential containers and associative containers.

Sequential container

There are three types of sequential containers: vector , deque , and list .

They are called sequential containers because the position of the element in the container has nothing to do with the value of the element, that is, the container is not sorted. When inserting an element into a container, specify where to insert it (tail, head, or somewhere in the middle), and where the element will be located.

1. Vector
continuous storage structure, each element is continuous in memory;
supports efficient random access and insert/delete operations at the end, but insert/delete operations in other positions are inefficient;

2. Deque
continuous storage structure, that is, each element is continuous in memory, similar to vector, the difference is that deque provides a two-level array structure, the first level is completely similar to vector, representing the actual container; the other The first address of the container is maintained at the level.
In this way, in addition to all the functions of vector, deque also supports efficient first-end insert/delete operations.

3. List is a
non-contiguous storage structure with a double-linked list structure. Each element maintains a pair of forward and backward pointers, so forward/backward traversal is supported.
Supports efficient random insert/delete operations, but random access is inefficient, and the overhead is relatively large due to the need to maintain additional pointers.

The choice of sequential container:
a. If you need random access operation, select vector;
b. If you already know the number of elements that need to be stored, select vector;
c. If you need to insert/delete randomly (not just at both ends), select list
d. Only select deque when insert/delete operations are required at the head end, otherwise select vector.
e. If you need to insert/delete randomly and access randomly, you need to make a compromise between vector and list.
f. When you want to store large objects of the responsible class, list is better than vector; of course, you can also use vector to store pointers to objects at this time, which will also achieve higher efficiency, but the maintenance of pointers is very error-prone, so Not recommended.

Note : The iterators of vector and deque support arithmetic operations, and the iterators of list can only perform ++/– operations, and do not support ordinary arithmetic operations.

Associative container

There are four types of associative containers: set , multiset , map , and multimap .

The elements in the associative container are sorted. When inserting an element, the container will place the element in an appropriate position according to a certain sorting rule, so the position cannot be specified when inserting an element.

By default, the elements in the associative container are sorted from smallest to largest (or from smallest to largest by keyword), and the <operator is used to compare the element or keyword size. Because it is sorted, associative containers have very good performance when looking up.

In addition to the above two types of containers, STL also shields some functions on the basis of the two types of containers, highlights or adds another part of the functions, and implements three container adapters: stack (stack), queue (queue), priority_queue (priority queue) .

Container function

All containers have the following two member functions:
int size(): returns the number of elements in the container object.
bool empty(): Determine whether the container object is empty.

Sequence containers and associative containers also have the following member functions:
begin(): returns an iterator pointing to the first element in the container.
end(): Returns an iterator pointing to the position after the last element in the container.
rbegin(): Returns a reverse iterator pointing to the last element in the container.
rend(): Returns a reverse iterator pointing to the position before the first element in the container.
erase(...): Delete one or several elements from the container.
clear(): Remove all elements from the container.

If a container is empty, the return values ​​of begin() and end() are equal, and the return values ​​of rbegin() and rend() are also equal.

Sequence container also has the following commonly used member functions:
front(): Returns a reference to the first element in the container.
back(): Returns a reference to the last element in the container.
push_back(): Add a new element at the end of the container.
pop_back(): Delete the element at the end of the container.
insert(...): Insert one or more elements. The parameters of this function are more complicated and are omitted here.

Example

(Here are only some containers and some function usage)
Sequential container:
vector container

void main()   //遍历、删除、插入
{
    
    
	vector<int> v1;
	v1.push_back(10);  //copy 到申请的容器
	v1.push_back(20); 
	v1.push_back(30); 

	//访问容器,定义一个迭代器:   相当于一个指针
	//正向遍历
	for(vector<int>::iterator it = v1.begin();it != v1.end();it++)
	{
    
    
		cout<<*it<<endl;
	}
	//逆向遍历
	for(vector<int>::reverse_iterator rit = v1.rbegin();rit != v1.rend();rit++)
	{
    
    
		cout<<*rit<<endl;
	}
	//区间删除
	v1.erase(v1.begin(),v1.begin()+2);
	//指定位置删除
	v1.erase(v1.begin());
	//遍历删除
	for(vector<int>::iterator dit = v1.begin();dit != v1.end();)
	{
    
    
		if(*dit == 2)
		{
    
    
			v1.erase(dit);   //当删除迭代器所指向元素时,erase让it自下移
		}
		else
		{
    
    
			dit++;
		}
	}
	//插入元素
	v1.insert (v1.begin(),100);    //头部插入数值100
	v1.insert (v1.end (),200);    //尾部插入数值200
	return;
}

deque container

void printd(deque<int> &d)
{
    
    
	for(deque<int>::iterator it = d.begin(); it != d.end();it++)
	{
    
    
		cout<<"元素"<<*it<<endl;
	}
}
void main()
{
    
    
	deque<int> d;
	d.push_back(1);  //在容器末尾增加新元素
	d.push_back(2);  
	d.push_front(3);  //在容器头尾增加新元素
	d.push_front(4);
	printd(d);

	deque<int>::iterator it = find(d.begin(),d.end(),3);  //查找指定元素3  找到时,返回该元素的迭代器;找不到时,返回end()。  
	if(it != d.end())
	{
    
    
		cout<<"3与第一个元素的距离为:"<<distance(d.begin (),it)<<endl;
	}

}

Associative container:
set container

void main()
{
    
    
	set<int> set1;
	//循环插入
	for(int i = 0;i < 3;i ++)
	{
    
    
		int tmp = rand() % 5;
		set1.insert(tmp);
	}
	//遍历打印集合
	for(set<int>::iterator it = set1.begin();it != set1.end(); it++)
	{
    
    
		cout<<*it<<endl;
	}
	//删除集合
	while(!set1.empty())
	{
    
    
		set<int>::iterator item = set1.begin();
		set1.erase(item);
	}
	return;
}

map container

//元素的添加、遍历、删除等基本操作
void main()
{
    
    
	//1、创建map对象
	map<int, string> map1;
	//方法1  添加元素  pair是一个有两个元素的结构体,方便使用,类似map :键值可以随意使用  
	//pair可以用来当做map的键值来插入 pair<T1,T2> p1 创建一个空的pair对象,有两个元素T1和T2,采用值初始化
	map1.insert(pair<int, string>(1,"hehe"));
	map1.insert(pair<int, string>(2,"xixi"));
	//方法2   添加元素 make_pair
	//make_pair
	map1.insert(make_pair(3,"haha"));
	map1.insert(make_pair(4,"huhu"));
	//方法3  添加元素
	map1.insert(map<int, string>::value_type(5,"kaka"));
	map1.insert(map<int, string>::value_type(6,"yiyi"));
	//方法4  数组方式插入数据
	map1[7] = "yaya";
	//容器遍历(迭代器)
	for(map<int, string>::iterator it = map1.begin();it != map1.end(); it++)
	{
    
    
		cout<<it->first<<"\t"<<it->second <<endl;
	}
	cout<<"遍历结束"<<endl;

	//容器的删除
	while(!map1.empty())
	{
    
    
		map<int, string>::iterator it = map1.begin();
		map1.erase(it);
	}

	//map查找
	map<int, string>::iterator it1 = map1.find(2);
	if(it1 != map1.end())
	{
    
    
		cout<<"不存在"<<endl;
	}
	else
	{
    
    
		cout<<it1->first<<"\t"<<it1->second<<endl;
	}

}

Guess you like

Origin blog.csdn.net/qq_46485161/article/details/114992407