C++ vector容器

一、vector 和 list 的区别

一、底层实现
1.vector的底层实现是顺序表,在内存中是一串连续的空间
2.list的底层实现是带头节点的双向循环链表,在内存中不是一串连续的空间

二、随机访问
1.vector支持随机访问,通过下标精准定位到一个元素,访问元素的时间复杂度是O(1);
2.list不支持随机访问,想要访问某一个元素只能遍历整个链表,访问元素的时间复杂度为O(N);

三、插入和删除
1.vector的插入和删除的效率低,因为在每次的删除或插入(除了尾插和尾删)都需要移动元素,时间复杂度为O(N)。
由于vector的特性,在插入过程中有可能会牵扯到空间的扩容和数据的搬移,这会导致效率更为低下。
2.list的插入和删除的效率较高,因为他不需要数据的移动,只需要更改插入或删除的位置上的前后节点的指向就行。时间复杂度为O(1)

4、迭代器失效问题

其底层实际就是一个指针,或者是对指针进行了封装因此迭代器失效,实际就是迭代器底层对应指针所指向的空间被销毁了,而使用一块已经被释放的空间,造成的后果是程序崩溃

关于vector插入操作的迭代器失效:

std::vector<int> v{1, 2, 3, 4, 5, 6};
    auto it = v.begin();
    v.resize(100, 8); 
     while(it != v.end())
    {
        cout<< *it << " " ;
        ++it;
    }

此时迭代器就已经失效了,解决方法:

for (const auto& element : v)
{
    // 使用element进行操作,而不是直接使用迭代器
    std::cout << element << " ";
}

在使用for-each循环时,编译器会自动处理迭代器的访问,它会确保在每次迭代时都重新计算正确的元素位置。

二、vector 重要函数assign(),resize(),reserve()

动态扩展:(这个概念很重要)
动态扩展并不是在原空间之后续接新空间,而是找到比原来更大的内存空间,将原数据拷贝到新空间,释放原空间

在这里插入图片描述

1.resize() 和 reserve()

resize(int num); //重新指定容器的长度为num,若容器变长,则以默认值0填充新位置
如果容器变短,则末尾超过容器长度的元素被删除
resize(int num,int elem); //重新指定容器的长度为num,若容器变长,则以elem填充新位置
如果容器变短,则末尾超过容器长度的元素被删除

resize和reserve函数本质都涉及了vector的内存存储空间,因为vector在内存中是连续存放的,所以当resize的空间大于现有的存储空间(capacity() 函数 返回当前vector在重新进行内存分配以前所能容纳的元素数量.)时,会重新选择更大的空间,并将所有元素复制过去。resize在初始化内存容量时有对值的初始化,所以此时push_back会产生size+1,内存容量不够,重新寻找更大的内存空间并复制所有元素,所以这个过程是很费事的。

	vector<int> vector1;
    vector1.resize(10);
    vector1.push_back(1);

一般vector容器扩容是按原容量的1.5倍扩容,可以使用reserve(),提前就让vector容器开好空间避免时间的浪费,所以先reserve()再pushback()可以大大增加效率

2.clear()

当调用clear()时,清除的是vector的内部数据,而不是vector本身容量,可以这样

int main()
{
vector<int> v;
v.resize(100);
	{
	vector <int> v2;
	swap(v2,v1);
	}
}
我们在块作用域中定义一个空的vector对象再相互交换,当块作用域结束后自动释放
这样就可以释放掉原来大内存的vector对象

结论:

vector::resize() 使用数组,效率最高,但是需要提前知道size大小

vector::reserve()使用 push_back(),效率一般,较原生有一定提升。

3.assign()

  1. 以 count 份 value 的副本替换内容。
  2. 以范围 [first, last) 中元素的副本替换内容。其中有任何一个迭代器是指向 *this 中的迭代器时行为未定义。

如果 InputIt 是整数类型,那么此重载与 (1) 拥有相同效果。
(C++11 前)

此重载只有在InputIt 满足老式输入迭代器 (LegacyInputIterator) 时才会参与重载决议。
(C++11 起)
3) 以来自 initializer_list ilist 的元素替换内容。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值