STL概念
vector基本概念 vector与数组的区别 vector容器的特点
vector动态扩展的含义 vector常用的接口示意
vector的构造函数 vector赋值操作
vector的容量和大小 vector的插入和删除 vector数据存取 vector互换容器 vector互换容器的使用方法 vector互换容器的用途
vector预留空间
vector基本概念
vector数据结构和数组非常相似,也称为单端数组。 vector也是一种顺序容器,在内存中连续排列。
vector与数组的区别
数组是静态空间,定义好之后,长度确定。 vector可以动态扩展。由于其大小(size)可变,常用于数组大小不可知的情况下来替代数组。
vector容器的特点
动态大小
vector容器的大小可以根据需要进行动态调整。 可以在运行时根据实际需求添加或删除元素,而无需在编译时确定容器的大小。 vector容器会自动处理内存管理。
连续存储
vector容器中的元素在内存中是连续存储的。 可以通过下标来访问容器中的元素,并且支持快速的随机访问。
自动扩容
当向vector容器中添加元素时,如果容器的当前大小不足以容纳新元素,容器会自动扩容。 扩容是通过重新分配内存并将原有元素复制到新内存空间中来实现的。 这种自动扩容的特性使得vector容器能够动态地适应元素的增长。
尾部操作高效
vector容器中的元素是连续存储的,因此在尾部进行插入和删除操作是高效的。 这是因为在尾部插入或删除元素时,不需要移动其他元素,只需调整尾部指针即可。
vector动态扩展的含义
并不是在在原空间后面续接新的空间,而是开辟一个更大的空间,将原数据拷贝到新空间,并删除原空间。
vector常用的接口示意
迭代器v.begin():起始元素的位置, v.end(): 最后一个元素之后的位置。 迭代器v.rbegin():末尾元素的位置, v.rend(): 第一个元素之前的位置。 front(): 第一个元素,back(): 末尾元素。 push_back(): 末尾添加元素,pop_back(): 末尾删除元素。 vector的迭代器是支持随机访问的迭代器,也就是说迭代器可以一下跳好几个。
vector的构造函数
vector v: 采用模板类实现,默认构造函数。 vector(v.begin(), v.end()): 将v对象从v.begin()到 v.end()之间的元素拷贝给正在创建的对象,包头不包尾。 vector(n, elem): 将n个elem拷贝给正在创建的对象。 vector(const vector &vec): 拷贝构造函数。
# include <iostream>
# include <vector>
using namespace std;
void print_vector ( vector< int > & vec)
{
for ( vector< int > :: iterator it = vec. begin ( ) ; it < vec. end ( ) ; it++ )
{
cout << * it << " " ;
}
cout << endl;
}
void test01 ( )
{
vector< int > arr1;
arr1. push_back ( 11 ) ;
arr1. push_back ( 22 ) ;
cout << "---------- arr1 ----------" ;
print_vector ( arr1) ;
vector< int > arr2 { 1 , 2 , 3 , 4 } ;
cout << "---------- arr2 ----------" ;
print_vector ( arr2) ;
vector< int > arr3 ( 4 ) ;
cout << "---------- arr3 ----------" ;
print_vector ( arr3) ;
vector< int > arr4 ( 5 , 3 ) ;
cout << "---------- arr4 ----------" ;
print_vector ( arr4) ;
vector< int > arr5 ( arr3) ;
cout << "---------- arr5 ----------" ;
print_vector ( arr5) ;
vector< int > arr6 ( arr2. begin ( ) , arr2. end ( ) ) ;
cout << "---------- arr6 ----------" ;
print_vector ( arr6) ;
vector< int > arr7 ( arr2. rbegin ( ) , arr2. rend ( ) ) ;
cout << "---------- arr7 ----------" ;
print_vector ( arr7) ;
}
int main ( )
{
test01 ( ) ;
system ( "pause" ) ;
return 0 ;
}
result:
-- -- -- -- -- arr1 -- -- -- -- -- 11 22
-- -- -- -- -- arr2 -- -- -- -- -- 1 2 3 4
-- -- -- -- -- arr3 -- -- -- -- -- 0 0 0 0
-- -- -- -- -- arr4 -- -- -- -- -- 3 3 3 3 3
-- -- -- -- -- arr5 -- -- -- -- -- 0 0 0 0
-- -- -- -- -- arr6 -- -- -- -- -- 1 2 3 4
-- -- -- -- -- arr7 -- -- -- -- -- 4 3 2 1
vector赋值操作
=重载赋值
函数原型 vector& operator=(const vector &vec), 重载等号运算符
assign赋值
v1.assign(beg迭代器,end迭代器), 将[beg迭代器,end迭代器) 之间的数据拷贝给被赋值的对象。 v1.assign(n,elem), 将n个elem的数据拷贝给被赋值的对象。
code:
# include <iostream>
# include <vector>
using namespace std;
void print_vector ( vector< int > & vec)
{
for ( vector< int > :: iterator it = vec. begin ( ) ; it < vec. end ( ) ; it++ )
{
cout << * it << " " ;
}
cout << endl;
}
void test01 ( )
{
vector< int > arr1{ 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 } ;
cout << "---------- arr1 ----------" << endl;
print_vector ( arr1) ;
vector< int > arr2;
arr2 = arr1;
cout << "---------- arr2 ----------" << endl;
print_vector ( arr2) ;
arr2. pop_back ( ) ;
arr2. pop_back ( ) ;
vector< int > arr3;
arr3. assign ( 5 , 3 ) ;
cout << "---------- arr3 ----------" << endl;
print_vector ( arr3) ;
vector< int > arr4;
arr4. assign ( arr1. begin ( ) , arr1. end ( ) - 4 ) ;
cout << "---------- arr4 ----------" << endl;
print_vector ( arr4) ;
}
int main ( )
{
test01 ( ) ;
system ( "pause" ) ;
return 0 ;
}
result:
-- -- -- -- -- arr1 -- -- -- -- --
0 1 2 3 4 5 6 7 8 9
-- -- -- -- -- arr2 -- -- -- -- --
0 1 2 3 4 5 6 7 8 9
-- -- -- -- -- arr3 -- -- -- -- --
3 3 3 3 3
-- -- -- -- -- arr4 -- -- -- -- --
0 1 2 3 4 5
vector的容量和大小
函数原型 用途 empty() 判断容器是否为空 capacity() 容器的容量,容量>=size size() 返回容器中元素的个数 resize(int num) 重新指定容器的长度(size)为num,若容器变长,则以默认数值填充新位置,如果容器变短,则末尾超出容器长度的元素被删除 resize(int num,elem) 重新指定容器的长度(size)为num,若容器变长,则以elem填充新位置,如果容器变短,则末尾超出容器长度的元素被删除
# include <iostream>
# include <vector>
using namespace std;
void print_vector ( vector< int > & vec)
{
for ( vector< int > :: iterator it = vec. begin ( ) ; it < vec. end ( ) ; it++ )
{
cout << * it << " " ;
}
cout << endl;
}
void test01 ( )
{
vector< int > arr1{ 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 } ;
cout << "---------- arr1 ----------" << endl;
print_vector ( arr1) ;
vector< int > arr2;
cout << "---------- arr2 ----------" << endl;
print_vector ( arr2) ;
if ( arr1. empty ( ) )
{
printf ( "arr1 is empty" ) ;
}
else
{
cout << "arr1.capacity: " << arr1. capacity ( ) << ", arr1.size: " << arr1. size ( ) << endl;
}
if ( arr2. empty ( ) )
{
printf ( "arr2 is empty\n" ) ;
}
vector< int > arr3;
arr3. assign ( arr1. begin ( ) , arr1. end ( ) ) ;
cout << "---------- arr3 ----------" << endl;
print_vector ( arr3) ;
cout << "arr3.capacity: " << arr3. capacity ( ) << ", arr3.size: " << arr3. size ( ) << endl;
arr3. resize ( 7 ) ;
cout << "---------- arr3.resize(7) ----------" << endl;
print_vector ( arr3) ;
cout << "arr3.capacity: " << arr3. capacity ( ) << ", arr3.size: " << arr3. size ( ) << endl;
arr3. resize ( 9 ) ;
cout << "---------- arr3.resize(9) ----------" << endl;
print_vector ( arr3) ;
cout << "arr3.capacity: " << arr3. capacity ( ) << ", arr3.size: " << arr3. size ( ) << endl;
arr3. resize ( 16 , 666 ) ;
cout << "---------- arr3.resize(16, 666); ----------" << endl;
print_vector ( arr3) ;
cout << "arr3.capacity: " << arr3. capacity ( ) << ", arr3.size: " << arr3. size ( ) << endl;
}
int main ( )
{
test01 ( ) ;
system ( "pause" ) ;
return 0 ;
}
reult:
-- -- -- -- -- arr1 -- -- -- -- --
0 1 2 3 4 5 6 7 8 9
-- -- -- -- -- arr2 -- -- -- -- --
arr1. capacity: 10 , arr1. size: 10
arr2 is empty
-- -- -- -- -- arr3 -- -- -- -- --
0 1 2 3 4 5 6 7 8 9
arr3. capacity: 10 , arr3. size: 10
-- -- -- -- -- arr3. resize ( 7 ) -- -- -- -- --
0 1 2 3 4 5 6
arr3. capacity: 10 , arr3. size: 7
-- -- -- -- -- arr3. resize ( 9 ) -- -- -- -- --
0 1 2 3 4 5 6 0 0
arr3. capacity: 10 , arr3. size: 9
-- -- -- -- -- arr3. resize ( 16 , 666 ) ; -- -- -- -- --
0 1 2 3 4 5 6 0 0 666 666 666 666 666 666 666
arr3. capacity: 16 , arr3. size: 16
vector的插入和删除
函数原型 用途 push_back(ele) 尾部插入元素ele insert(const_iterator pos, ele) 迭代器指向位置pos插入元素ele insert(const_iterator pos, int count, ele) 迭代器指向位置pos插入count元素ele erase(const_iterator pos) 删除迭代器指向的元素 erase(const_iterator start, const_iterator end) 删除迭代器从start到end之间的元素 clear() 删除容器中所有元素
code:
# include <iostream>
# include <vector>
using namespace std;
void print_vector ( vector< int > & vec)
{
for ( vector< int > :: iterator it = vec. begin ( ) ; it < vec. end ( ) ; it++ )
{
cout << * it << " " ;
}
cout << endl;
}
void test01 ( )
{
vector< int > v1;
v1. push_back ( 11 ) ;
v1. push_back ( 22 ) ;
v1. push_back ( 33 ) ;
cout << "---------- v1尾插 ----------" << endl;
print_vector ( v1) ;
v1. pop_back ( ) ;
cout << "---------- v1尾删 ----------" << endl;
print_vector ( v1) ;
v1. insert ( v1. begin ( ) + 1 , 666 ) ;
cout << "---------- v1.insert(v1.begin()+1,666) ----------" << endl;
print_vector ( v1) ;
v1. insert ( v1. begin ( ) , 5 , 666 ) ;
cout << "---------- v1.insert(v1.begin(), 3, 888) ----------" << endl;
print_vector ( v1) ;
v1. erase ( v1. begin ( ) ) ;
cout << "---------- v1.erase(v1.begin()) ----------" << endl;
print_vector ( v1) ;
v1. erase ( v1. begin ( ) , v1. end ( ) - 2 ) ;
cout << "---------- v1.erase(v1.begin(), v1.end()-2) ----------" << endl;
print_vector ( v1) ;
v1. clear ( ) ;
cout << "---------- v1.clear() ----------" << endl;
print_vector ( v1) ;
}
int main ( )
{
test01 ( ) ;
system ( "pause" ) ;
return 0 ;
}
result:
-- -- -- -- -- v1尾插 -- -- -- -- --
11 22 33
-- -- -- -- -- v1尾删 -- -- -- -- --
11 22
-- -- -- -- -- v1. insert ( v1. begin ( ) + 1 , 666 ) -- -- -- -- --
11 666 22
-- -- -- -- -- v1. insert ( v1. begin ( ) , 3 , 888 ) -- -- -- -- --
666 666 666 666 666 11 666 22
-- -- -- -- -- v1. erase ( v1. begin ( ) ) -- -- -- -- --
666 666 666 666 11 666 22
-- -- -- -- -- v1. erase ( v1. begin ( ) , v1. end ( ) - 2 ) -- -- -- -- --
666 22
-- -- -- -- -- v1. clear ( ) -- -- -- -- --
vector数据存取
函数原型 用途 at(int idx) 返回索引idx所指的数据 operator[] 返回索引idx所指的数据 front() 返回容器中的第一个数据元素 back() 返回容器中的最后一个数据元素
code:
# include <iostream>
# include <vector>
using namespace std;
void print_vector ( vector< int > & vec)
{
for ( int i_loop = 0 ; i_loop < vec. size ( ) ; i_loop++ )
{
cout << vec[ i_loop] << " " ;
}
cout << endl;
}
void print_vector_at ( vector< int > & vec)
{
for ( int i_loop = 0 ; i_loop < vec. size ( ) ; i_loop++ )
{
cout << vec. at ( i_loop) << " " ;
}
cout << endl;
}
void test01 ( )
{
vector< int > v1{ 11 , 22 , 33 , 44 , 55 , 66 } ;
print_vector ( v1) ;
print_vector_at ( v1) ;
cout << "vector容器中的第一个元素: " << v1. front ( ) << endl;
cout << "vector容器中的最后一个元素: " << v1. back ( ) << endl;
}
int main ( )
{
test01 ( ) ;
system ( "pause" ) ;
return 0 ;
}
result:
11 22 33 44 55 66
11 22 33 44 55 66
vector容器中的第一个元素: 11
vector容器中的最后一个元素: 66
vector互换容器
实现两个容器内元素互换 v1.swap(vec), v1与vec中的元素互换
vector互换容器的使用方法
code:
# include <iostream>
# include <vector>
using namespace std;
void print_vector ( vector< int > & vec)
{
for ( vector< int > :: iterator it= vec. begin ( ) ; it< vec. end ( ) ; it++ )
{
cout << * it << " " ;
}
cout << endl;
}
void test01 ( )
{
vector< int > v1{ 11 , 22 , 33 , 44 , 55 , 66 } ;
vector< int > v2{ 99 , 88 , 66 , 77 } ;
cout << "---------- swap前 ----------" << endl;
cout << "v1中的元素:" ;
print_vector ( v1) ;
cout << "v1.capacity: " << v1. capacity ( ) << ", v1.size: " << v1. size ( ) << endl;
cout << "v2中的元素:" ;
print_vector ( v2) ;
cout << "v2.capacity: " << v2. capacity ( ) << ", v2.size: " << v2. size ( ) << endl;
cout << "\n---------- swap后 ----------" << endl;
v1. swap ( v2) ;
cout << "v1中的元素:" ;
print_vector ( v1) ;
cout << "v1.capacity: " << v1. capacity ( ) << ", v1.size: " << v1. size ( ) << endl;
cout << "v2中的元素:" ;
print_vector ( v2) ;
cout << "v2.capacity: " << v2. capacity ( ) << ", v2.size: " << v2. size ( ) << endl;
}
int main ( )
{
test01 ( ) ;
system ( "pause" ) ;
return 0 ;
}
result:
-- -- -- -- -- swap前 -- -- -- -- --
v1中的元素: 11 22 33 44 55 66
v1. capacity: 6 , v1. size: 6
v2中的元素: 99 88 66 77
v2. capacity: 4 , v2. size: 4
-- -- -- -- -- swap后 -- -- -- -- --
v1中的元素: 99 88 66 77
v1. capacity: 4 , v1. size: 4
v2中的元素: 11 22 33 44 55 66
v2. capacity: 6 , v2. size: 6
vector互换容器的用途
code:
# include <iostream>
# include <vector>
using namespace std;
void print_vector ( vector< int > & vec)
{
for ( vector< int > :: iterator it = vec. begin ( ) ; it < vec. end ( ) ; it++ )
{
cout << * it << " " ;
}
cout << endl;
}
void test01 ( )
{
vector< int > v1;
for ( int i_loop = 0 ; i_loop < 10000 ; i_loop++ )
{
v1. push_back ( i_loop) ;
}
cout << "---------- swap前 ----------" << endl;
cout << "v1.capacity: " << v1. capacity ( ) << ", v1.size: " << v1. size ( ) << endl;
v1. resize ( 3 ) ;
cout << "---------- v1.resize(3) ----------" << endl;
print_vector ( v1) ;
cout << "v1.capacity: " << v1. capacity ( ) << ", v1.size: " << v1. size ( ) << endl;
vector < int > ( v1) . swap ( v1) ;
cout << "\n---------- swap后 ----------" << endl;
cout << "v1.capacity: " << v1. capacity ( ) << ", v1.size: " << v1. size ( ) << endl;
}
int main ( )
{
test01 ( ) ;
system ( "pause" ) ;
return 0 ;
}
result:
-- -- -- -- -- swap前 -- -- -- -- --
v1. capacity: 12138 , v1. size: 10000
-- -- -- -- -- v1. resize ( 3 ) -- -- -- -- --
0 1 2
v1. capacity: 12138 , v1. size: 3
-- -- -- -- -- swap后 -- -- -- -- --
v1. capacity: 3 , v1. size: 3
vector预留空间
减少vector在动态扩展容量时的扩展次数 且看下面的代码:
code:
void test01 ( )
{
int num = 0 ;
vector< int > v1;
int * pt = NULL ;
for ( int i_loop = 0 ; i_loop < 10000 ; i_loop++ )
{
v1. push_back ( i_loop) ;
if ( & v1[ 0 ] != pt)
{
pt = & v1[ 0 ] ;
num++ ;
}
}
cout << "num: " << num << endl;
}
int main ( )
{
test01 ( ) ;
system ( "pause" ) ;
return 0 ;
}
result:
num: 24
从代码中可以看出,空间一共开辟了24次,当然也伴随着旧的空间释放,这些操作其实就是浪费资源。 试问怎么解决呢?且看下面代码
code:
# include <iostream>
# include <vector>
using namespace std;
void print_vector ( vector< int > & vec)
{
for ( vector< int > :: iterator it = vec. begin ( ) ; it < vec. end ( ) ; it++ )
{
cout << * it << " " ;
}
cout << endl;
}
void test01 ( )
{
int num = 0 ;
vector< int > v1;
v1. reserve ( 10000 ) ;
int * pt = NULL ;
for ( int i_loop = 0 ; i_loop < 10000 ; i_loop++ )
{
v1. push_back ( i_loop) ;
if ( & v1[ 0 ] != pt)
{
pt = & v1[ 0 ] ;
num++ ;
}
}
cout << "num: " << num << endl;
}
int main ( )
{
test01 ( ) ;
system ( "pause" ) ;
return 0 ;
}
result:
num: 1
从代码中可以看出,空间一共开辟了1次,这是因为使用v1.reserve(空间大小),系统会先预留一片空间,如果没超出,就不会开辟新的。