vector使用方法
1.定义一维数组:
vector<int> vec; vector<int> vec(100);
vector<int> vec(100, 0);//创建长度100,初始值全为0的数组
获取一维数组的长度: vec.size();
2.定义二维数组:
vector<vector<int> > vec(m, vector<int>(n)); //创建m*n 的二维数组, 这里由于每行都是一个vector,所以是可以改变每行的长度的
获取二维数组的行数:vec.size();
获取二维数组的列数: vec[0].size();
3.vector容器的方法:
- int size() : 返回容器内的元素个数
- void clear() :清空所有元素
- bool empty() :判断是否为空
- void push_back(int x) :在表尾添加x
- void insert(position, n, x) : 在position开始,插入n个元素,元素初始值为x
- void pop_back() :删除表尾元素
- back() :返回表尾元素
- front() :返回表头元素
- operator[] (int idx) :返回vector中idx索引位置的对象
- int capacity() :返回vector的内部容量
- void resize(size_type new_size); 重新调整大小
- void reserve(int capacity) :设置vector的新容量
- reverse(nums.begin(), nums.end()); 翻转
- sort(nums.begin(),nums.end()); 排序O(nlog(n))
list使用方法:
1.list的构造函数
list<int> ilist() 声明一个空列表;
list(n) 声明一个有n个元素的列表,每个元素都是由其默认构造函数T()构造出来的
list(n,val) 声明一个由n个元素的列表,每个元素都是由其复制构造函数T(val)得来的
list(n,val) 声明一个和上面一样的列表
list(first,last) 声明一个列表,其元素的初始值来源于由区间所指定的序列中的元素
2.list的元素操作
push_front() 从头插入,作为头节点
push_back() 从尾部插入
pop_front() 移除头节点
pop_back() 移除尾节点
clear() 清除整个链表
erase(position)移除position处的元素
remove(cosnt T& value) 将值为value的元素全部删除
unique() 移除数值相同的连续元素,注意:只有“连续而相同的元素”,才会被移除剩一个
void splice(iterator position, list& x) 将x接合于position所指位置之前。x必须不同于*this
void splice(iterator postion, list&, iterator i) 将i所指元素接合于position所指位置之前。position和i可以指向同一个list
void splice(iterator position, list&, iterator first, iterator last)将[first, last)内的所有元素接合于position所指元素之前
void merge(list<T, Alloc>& x) 将x合并到*this身上。注意:两个lists的内容都必须先经过递增排序,合并之后的内容依然有序
void reverse() 将*this的内容逆向重置
void sort() list不能使用STL算法库的sort()方法,必须使用自己的sort()方法
deque的使用方法
在介绍STL的deque的容器之前,我们先来总结一下vector和list的优缺点。vector在内存中是分配一段连续的内存空间进行存储,其迭代器采用原生指针即可,因此其支持随机访问和存储,支持下标操作符,节省空间。但是其在分配的内存不够的情况下,需要对容器整体进行重新分配、拷贝和释放等操作,而且在vector中间插入或删除元素效率很低。
而list是以节点形式来存放数据,使用的是非连续的内存空间来存放数据,因此,在其内部插入和删除元素的时间复杂度都是O(1),但是其不支持随机访问和存取,不支持下标,而且比vector占用的内存要多。
综合上述的优缺点,我们貌似需要一个支持随机访问和存取,支持下标访问,而且插入和删除的效率高的容器。于是,STL的deque诞生了
1.deque的中控器
deque为了维持整体连续的假象,设计一个中控器,其用来记录deque内部每一段连续空间的地址。大体上可以理解为deque中的每一段连续空间分布在内存的不连续空间上,然后用一个所谓的map作为主控,记录每一段内存空间的入口,从而做到整体连续的假象。其布局大概如下
看完图解,再来看看源码会很好理解的。
template <class T, class Alloc = alloc, size_t BufSiz = 0>
class deque {
public:
typedef T value_type;
typedef value_type* pointer;
typedef const value_type* const_pointer;
typedef value_type& reference;
typedef const value_type& const_reference;
typedef size_t size_type;
typedef ptrdiff_t difference_type;
protected:
typedef pointer* map_pointer;
// 指向map, map是一个连续的空间, 其每个元素都是一个指向缓冲区的指针
map_pointer map;
size_type map_size; // map容量
}
抛弃型别定义,我们可以看到map实际上就是一个指向指针的指针(T**),map所指向的是一个指针,该指针指向型别为T的一块内存空间。
2.deque的迭代器
deque提供的是一个随机访问迭代器,由于是分段连续空间,其必须记录当前元素所在段的信息,从而在该段连续空间的边缘进行前进或者后退的时候能知道跳跃到的上一个或下一个缓冲区。deque必须完完全全地掌握和控制这些信息,以达到正确地跳跃!
deque的迭代器中有cur,first,last和node四个指针,前三个记录了迭代器与缓冲区的联系,最后一个记录了迭代器于中控器的关系。从下面这张图可以很好的看出其关系:
deque的构造和析构函数:
deque<elem> c1; deque<elem> c1(c2); deque<elem> c1(n); deque<elem> c1(n, x);
deque<elem> c1(begein, end);
c1.~deque<elem>();
deque::assign() 替换容器的内容。
void assign( size_type count, const T& value ); 以 count 份 value 的副本替换内容。
void assign( InputIt first, InputIt last ); 以范围 [first, last) 中元素的副本替换内容
若 InputIt 为整数类型,则此重载与 (1) 拥有相同效果。
void assign( std::initializer_list<T> ilist ); 以来自 initializer_list ilist 的元素替换内容
容量:
bool empty();
size_type size() const; 返回容器中的元素数
size_type max_size() const; 返回根据系统或库实现限制的容器可保有的元素最大数量
void shrink_to_fit(); 请求移除未使用的容量。
修改器:
void clear(); 从容器擦除所有元素。此调用后 size() 返回零。
void insert( iterator pos, size_type count, const T& value );
template< class InputIt > void insert( iterator pos, InputIt first, InputIt last);
iterator insert( iterator pos, const T& value );
template< class... Args > iterator emplace( const_iterator pos, Args&&... args ); 直接于 pos 前插入元素到容器中。通过 std::allocator_traits::construct 构造元素,它典型地用布置 new 在容器所提供的位置原位构造元素。将参数 args... 作为 std::forward<Args>(args)... 转发给构造函数。
void push_back(value);
void push_front(value);
void pop_back();
void pop_front();
void resize(count);
void swap( deque& other ); 将内容与 other 的交换。不在单个元素上调用任何移动、复制或交换操作。
void erase(value);
void erase_if(std::deque<T,Alloc>& c, Pred pred); 从容器中擦除所有满足 pred 的元素。等价于 c.erase(std::remove_if(c.begin(), c.end(), pred), c.end());
stack的使用:
SGI STL以deque作为缺省情况下stack的底部结构(也可以用list,vector作为底部结构),STL stack往往不被归类为container, 而被归类为container adapter。
stack没有迭代器!
常用方法:
bool empty()
size_type size()
reference top() ;
void push(value);
void pop();
queue的使用:
同样,SGI STL 以deque作为缺省情况下queue的底部结构(也可以用list作为底层结构)。
queue同样没有迭代器!
常用方法:
bool empty()
size_type size()
reference front();
reference back();
void push(value);
void pop();
priority_queue使用方法
缺省情况下priority_queued使用max_heap。max_heap是一个以vector表现的完全二叉树。max_heap 可以满足priority_queue所需要的“依权值高低自动递减排序”的特性。
构造函数:
常用方法:
const_reference top(); 返回到 priority_queue 顶元素的引用。此元素将在调用 pop() 时被移除。
size_type size() 返回底层容器中的元素数
void push(value);
void pop();