- Vector
- deque
- list
- forwa_list
- Stack
- Queue
Vector:
vector是动态数组,支持列表初始化即,vector<int> vect{1, 2, 3};
系统自动分配内存,支持随机访问,除了在尾端插入和删除,其他地方的操作需要O(n)。
常用到的插入,删除,查找:
vector<int> vect;
//Insert element in the end of array. If the size of vect is greater than capacitance, reallocate the memory
vect.push_back(1);
//Erase the last element
vect.push_pop(); //没有返回值哦!
vect.erase(vect.end());
vect.erase(b, e); //移除[b, e)之间的元素, b和e都是迭代器
//Insert the element in any position
vect.insert(it, elem); // it is a iterator point to the position where ele want to be inserted
//Access the first/last element
vector<int> vect1{1, 0};
int a = vect1.front(); // a = 1;
int b = vect1.back(); // b = 0;
vect1[idx] //没有越界检测(不过vs编译器有。。)
vect1.at(idx); //有越界检测
size_t size = vect1.capacity(); //返回当前容器最多能存储元素的个数
vect1.max_size(); //返回vect1里面能存储最多的数
//Find an element in vector
vector里面没有find的成员函数!!!
1. use the generic algorithm
std::find(vect.begin(), vect.end(), val); //在[begin, end)之间查找,如果找到,返回一个迭代器/指针,指向val的位置;如果没找到,就返回end()的位置
deque:
双端队列(double-end-queue),和vector非常相似,都是通过动态数组管理内存,支持随机访问,并且和vector用相同的接口。不同点在于,deque的头尾两端都是开放的。因此,deque在头尾插入和删除都是O(1)。
deque在内存中的实现是通过一些独立的内存块,如下图所示,第一个和最后一个内存块往相反的方向增长。
Note:deque不支持内存重新分配控制,因此,当有元素插入到容器中间时(非两端),那么这时候指向deque的指针、迭代器和引用都会失效!
什么时候使用deque合适呢?
1. 需要在容器前后两端插入和删除元素的时候
2. 不需要指向容器中的元素
deque常用操作: deque里面没有capacity()函数
#include<deque>
deque<int> q{1, 2, 3};
q.empty();
q.size(); //returns the current number of elements
q.max_size(); //return the maximum number of elements possible
q.shrink_to_fit(); // request to reduce capacity to fit number of elements
q[idx];
q.at(idx);
q.front(); //return the first element(no check whether a first element exits)
q.back(); //return the last element(no check ...)
q.assign(n, elem); //assign n copies of element elem
q.assign(beg, end); //assign all the elements of the range [beg, end)
swap(c1, c2); //swaps the data of c1 and c2
q.push_back(elem); //append a copy of elem at the end
q.pop_back(); //remove the last element (does not return it)
q.push_front(elem); //insert a copy of elem at the beginning
q.pop_front(); //remove the first element
q.insert(pos, elem); //insert a copy of elem before iterator position pos and return the position of the new element
q.insert(pos, n, elem); //insert n copies of elem before iterator position pos and return the position of the first new element
q.erase(pos); //remove the element at iterator position pos and return the position of the next element
q.erase(beg, end); //return ...
q.resize(num); //change the number of elements to num (if size() grows new elements are created by their default constructor)
q.clear(); //remove elements (empties the container)
list
list是一个双向链表(doubly linked list),list的内部结构和vector,array,deque完全不同。list里面有两个指针(anchors),分别指向第一个元素和最后一个元素,每个元素都有指向自己前驱和后驱的指针。
list和array,vector,deque的不同点:
1. list不能随机访问元素,即不能用[idx]。如果要要访问某个元素,一定要遍历,因此效率很慢,但是访问第一个和最后一个元素还是很快的;
2. 在某个位置插入和删除元素只需要O(1),因为不需要移动list中的元素(强调的是插入的操作,不包括找到要插入位置所需的(线性)时间)
3. 插入和删除不会让指向容器中元素的指针、引用、迭代器失效
4. list支持每次操作成功或者失败的异常处理
list的操作:
#include<list>
list<int> ll{1, 2, 3};
ll.empty();
ll.size(); //return the current number of element in list with size_t type
ll.max_size(); //返回可存放的最大数字
ll.assign(n, elem); //assign n copies of element elem
ll.assign(beg, end); //assign the elements of the range [beg, end)
swap(c1, c2); //swap the data of c1 and c2
ll.front(); //returns the first element(no check if the first element exits)
ll.back(); //returns the last ...
ll.push_back(elem);
ll.pop_back();
ll.push_front();
ll.pop_front();
ll.insert(pos, elem); //Inserts a copy of elem before iterator position pos and returns
the position of the new element
ll.insert(pos, beg, end);
ll.erase(pos); //Removes the element at iterator position pos and returns the
position of the next element
ll.erase(beg, end); //Removes all elements of the range [beg,end) and returns the
position of the next element
ll.remove(val); //Removes all elements with value val
ll.remove_if(op); //Removes all elements for which op(elem) yields true
ll.resize(num); //Changes the number of elements to num (if size() grows
new elements are created by their default constructor)
ll.resize(num, elem); //Changes the number of elements to num (if size() grows
new elements are copies of elem)
ll.clear(); //removes all elements(empties the contianer)
Forward_list:
Stack:
是一种后进先出的容器,在STL里面本质上是适配器(Adaptor),本身并没有实现什么结构和算法,只是把改造了已有容器的接口。
所有的容器适配器,都要满足增加,移除元素的操作,因此不能用forward_list和array来实现,。
栈,要求push_back, pop_back, pop_back, and back操作,因此可以用除了上面的两个以外的容器实现。
stack<int> intStack; //empty stack
//fill up the stack
for(size_t ix = 0; ix != 10; ++ix){
intStack.push(ix); //intStack holds 0...9 inclusive
}
while(!intStack.empty()){
int value = intStack.top();
//code that use value
intStack.pop(); //pop the top element, and repeat
}
Stack操作:
s.pop(); // Remove, but does not return, the top element from the stack
s.top(); //Return, but does not remove, the top element on the stack
s.push(item);
s.emplace(args); //Creates a new top element on the stack by copying or moving item, or by constructing the element from args
The Queue Adaptors:
queue 和 priority_queue
q.pop(); //Removes, but does not return, the front element
q.front(); //Return, but does not remove
q.back(); //返回最后一个元素,只有queue能用
q.top(); //返回优先级最高的元素,只有priority_queue能用
q.push(item);
q.emplace(args); //增加元素