C++STL之vector 容器

简介: C++STL之vector 容器

🍒一、vector 容器基本概念

       什么是vector?

       vector 是 C++ STL 中的一种顺序容器,其内部实现是通过动态数组实现的,可以存储任意类型的数据。vector可以自动调整大小,当容器中的元素数量增加或减少时,可以自动重新分配内存。vector支持随机访问,可以像数组一样访问其中的元素,同时也支持在容器的末尾添加和删除元素。vector是C++标准库中的一个重要组件。

 vector基本概念

  1. 数据存储方式: vector 内部使用动态数组实现数据的存储,因此它可以随意扩展和缩小自身的存储空间,而且相比于数组,vector 更加灵活和方便。
  2. 大小和容量: vector 具有两个概念——大小和容量,大小表示当前 vector 中实际存储的元素数量,而容量则表示 vector 内部实际分配的存储空间大小。当 vector 容量不足时,会自动重新分配内存并将元素复制到新的内存中。
  3. 迭代器: vector 提供了迭代器,可以通过迭代器来遍历 vector 中的元素。vector 有很多种迭代器,比如 iteratorconst_iteratorreverse_iteratorconst_reverse_iterator 等。
  4. 增删改查操作: vector 提供了很多种便捷的增增删改查操作,比如 push_backpop_backinserteraseclear 等。
  5. 特殊操作: vector 还提供了一些特殊的操作,比如使用 reserve 函数预分配内存、使用 resize 函数改变 vector 的大小等等。

        vector的结构

       一图让你明白~


🍈二、vector 迭代器

       Vector 维护一个线性空间, 所以不论元素的型别如何, 普通指针都可以作为vector 的迭代器, 因为 vector 迭代器所需要的操作行为, 如 operaroe, operator->,operator++, operator--, operator+, operator-, operator+=, operator-=, 普通指针天生具备。 Vector 支持随机存取, 而普通指针正有着这样的能力。 所以 vector 提供的是随机访问迭代器(Random Access Iterators)。根据上述描述, 如果我们写如下的代码: Vector::iterator it1; Vector::iterator it2; it1 的型别其实就是 Int,it2 的型别其实就是 Teacher*。


🍇 三、vector API

        1、vector 构造函数

vector<T> v; //采用模板实现类实现, 默认构造函数
vector(v.begin(), v.end());//将 v[begin(), end())区间中的元素拷贝给本身。
vector(n, elem);//构造函数将 n 个 elem 拷贝给本身。
vector(const vector &vec);//拷贝构造函数。

2、赋值与交换语句

assign(beg, end);//将[beg, end)区间中的数据拷贝赋值给本身。
assign(n, elem);//将 n 个 elem 拷贝赋值给本身。
vector& operator=(const vector &vec);//重载等号操作符
swap(vec);// 将 vec 与本身的元素互换。

      🌰

void printVectorInt(vector<int>& v)
 {
   for (vector<int>::iterator it = v.begin(); it != v.end(); it++)//v.begin()和v.end()可以看作是指向头尾的指针
     {
     cout << *it << " ";
     }
   cout << endl;
 }
 void test01()
 {
   vector<int> v1(5, 10);
   vector<int> v2;
   //vector& operator=(const vector &vec);//重载等号操作符
   v2 = v1;
   printVectorInt(v2);
   //assign(n, elem);//将n个elem拷贝赋值给本身
   vector<int> v3;
   v3.assign(5, 100);
   printVectorInt(v3);
   //assign(beg, end);//将[beg, end)区间中的数据拷贝赋值给本身
   vector<int> v4;
   v4.assign(v3.begin(), v3.end());
   printVectorInt(v4); 
   //swap(vec);// 将vec与本身的元素互换。
   vector<int> v5(5, 20);
   vector<int> v6(10, 40);
   printVectorInt(v5);
   printVectorInt(v6);
   v5.swap(v6);
   printVectorInt(v5);
   printVectorInt(v6);
   }

  运行效果:


        3、vector大小操作

size();//返回容器中元素的个数
empty();//判断容器是否为空
resize(int num);//重新指定容器的长度为 num, 若容器变长, 则以默认值填充新位
//置。 如果容器变短, 则末尾超出容器长度的元素被删除。
resize(int num, elem);//重新指定容器的长度为 num, 若容器变长, 则以 elem 值填
//充新位置。 如果容器变短, 则末尾超出容器长>度的元素被删除。
capacity();//容器的容量
reserve(int len);//容器预留 len 个元素长度, 预留位置不初始化, 元素不可访问。

   🌰1

void printVectorInt(vector<int>& v)
 {
   for (vector<int>::iterator it = v.begin(); it != v.end(); it++)
//v.begin()和v.end()可以看作是指向头尾的指针
     {
     cout << *it << " ";
     }
   cout << endl;
 }
void test02()
 { vector<int> v;
 v.push_back(10);
 v.push_back(20);
 v.push_back(30);
 v.push_back(40);
 if (v.empty())
 {
   cout << "v容器为空" << endl;
   }
 else
 {
   cout << "容器非空" << endl;
   cout << "size = " << v.size() << endl;
   cout << "capacity = " << v.capacity() << endl;
   //容量 >= size
     }
 printVectorInt(v);//10 20 30 40
 //resize(int num);//重新指定容器的长度为num
 //多出的部分 自动补0
 v.resize(8);
 printVectorInt(v);//10 20 30 40 0 0 0 0
 //resize(int num, elem);//重新指定容器的长度为num,
 //若容器变长,则以elem值填充
 v.resize(10, 5);
 printVectorInt(v);//10 20 30 40 0 0 0 0 5 5
 v.resize(2);
 printVectorInt(v);//10 20
 }

     运行效果:

        🌰2(resize 作用的容器的大小 不会更改容器的容量)

void test03()
 {
   vector<int> v;
   v.push_back(10);
   v.push_back(20);
   v.push_back(30);
   v.push_back(40); 
   v.push_back(50);
   v.push_back(60);
     cout << "size = " << v.size() << endl;
   cout << "capactiy = " << v.capacity() << endl;
   printVectorInt(v);
     cout << "‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐" << endl;
   v.resize(2);
   cout << "size = " << v.size() << endl;
   cout << "capactiy = " << v.capacity() << endl;
   printVectorInt(v);
   }

运行效果:


       4、使用resize swap收缩容器的容量(难点)

       在C++中,vector是一种动态数组容器。当元素个数超过容器当前容量时,会自动分配更多的内存来存储元素。但是,当容器中元素个数减少时,vector并不会自动收缩内存,而是会保留之前分配的内存空间,浪费了内存资源。


       为了解决这个问题,可以使用resize()和swap()函数来收缩容器的容量。


       resize()函数可以用来改变容器的大小,它有两个重载版本:

  1. resize(n):将容器的大小改为n,如果n小于容器当前大小,则会删除超出n的元素;如果n大于容器当前大小,则会在容器末尾添加默认值的元素,比如int类型的默认值为0。resize(n, value):将容器的大小改为n,如果n小于容器当前大小,则会删除超出n的元素;如果n大于容器当前大小,则会在容器末尾添加value值的元素。

       使用resize()函数可以有效地收缩容器的大小,但是它并不能释放容器的内存空间。为了释放内存空间,可以使用swap()函数。


       swap()函数可以交换两个容器的元素,使用swap()函数可以将一个空的vector容器和另一个容器交换,从而释放空的容器之前占用的内存空间。

       🌰

void test04()
 {
   vector<int> v;
   for (int i = 0; i < 1000; i++)
     {
     v.push_back(i);
     }
   cout << "size = " << v.size() << endl;//1000
   cout << "capactiy = " << v.capacity() << endl;//1066
     //使用reszie将空间 置成10个元素(可以吗?)
     v.resize(10);//不能修改容量 只能修改size
   cout << "size = " << v.size() << endl;//10
   cout << "capactiy = " << v.capacity() << endl;//1066
     //使用swap收缩容器的容量
     vector<int>(v).swap(v);
     cout << "size = " << v.size() << endl;//10
   cout << "capactiy = " << v.capacity() << endl;//10
   }

 运行效果:

       一图让你了解~


       5、reserve预留空间大小

       🌰

//reserve(int len);//容器预留len个元素长度,预留位置不初始化,元素不可访问
 void test05()
 {
   vector<int> v;
    //一次性 给够空间 叫空间预留
   v.reserve(1000);//预留空间 1000个元素
    int* p = NULL;
   int count = 0;
   for (int i = 0; i < 1000; i++)
     {
     v.push_back(i);
     if (p != &v[0])
       {
       count++;
       p = &v[0];
       }
     }
   cout << "重新另寻空间次数:" << count << endl; 
}

运行效果:

       如果没有:v.reserve(1000); 结果为11

       如果有:v.reserve(1000); 结果为1


       6、数据的存取

at(int idx); //返回索引 idx 所指的数据, 如果 idx 越界, 抛出 out_of_range 异
常。
operator[];//返回索引 idx 所指的数据, 越界时, 运行直接报错
front();//返回容器中第一个数据元素
back();//返回容器中最后一个数据元素

🌰

void test06()
 {
   vector<int> v;
   v.push_back(10);
   v.push_back(20);
   v.push_back(30);
   v.push_back(40);
     printVectorInt(v);//10 20 30 40
   cout << v[2] << endl;//30
   cout << v.at(2) << endl;//30
   //[] 越界 不抛出异常
     //at 越界 抛出异常
     cout << "front = " << v.front() << endl;//10
   cout << "back = " << v.back() << endl;//40
   }

 运行效果:


       7、插入和删除

insert(const_iterator pos, int count,ele);//迭代器指向位置 pos 插入 count个元素 ele.
push_back(ele); //尾部插入元素 ele
pop_back();//删除最后一个元素
erase(const_iterator start, const_iterator end);//删除迭代器从 start 到 end 之间的元素
erase(const_iterator pos);//删除迭代器指向的元素
clear();//删除容器中所有元素

       🌰

void test07()
 {
   vector<int> v;
   v.push_back(10);
   v.push_back(20);
   v.push_back(30);
   v.push_back(40);
   printVectorInt(v);//10 20 30 40
     //insert(const_iterator pos, int count,ele);
     //迭代器指向位置pos插入count个元素ele.
     v.insert(v.begin() + 2, 3, 100);
   printVectorInt(v);//10 20 100 100 100 30 40
     //尾部删除:pop_back();//删除最后一个元素
     v.pop_back();//将40删除了
   printVectorInt(v);//10 20 100 100 100 30
     //erase(const_iterator start, const_iterator end);
     //删除迭代器从start到end之间的元素
     v.erase(v.begin() + 2, v.end()-1);
   printVectorInt(v);//10 20 30
     //erase(const_iterator pos);//删除迭代器指向的元素
     v.erase(v.begin() + 1);//删除20的位置
   printVectorInt(v);//10 30
     cout << "size = " << v.size() << ", capacity = " << v.capacity() << endl;
     //clear();//删除容器中所有元素
     v.clear();
   printVectorInt(v);//啥也没有
   cout << "size = " << v.size() << ", capacity = " << v.capacity() << endl;
   }

 运行效果:


               感谢你耐心的看到这里ღ( ´・ᴗ・` )比心,如有哪里有错误请踢一脚作者o(╥﹏╥)o!  

相关文章
|
10天前
|
算法 C语言 C++
【c++丨STL】list的使用
本文介绍了STL容器`list`的使用方法及其主要功能。`list`是一种双向链表结构,适用于频繁的插入和删除操作。文章详细讲解了`list`的构造函数、析构函数、赋值重载、迭代器、容量接口、元素访问接口、增删查改操作以及一些特有的操作接口如`splice`、`remove_if`、`unique`、`merge`、`sort`和`reverse`。通过示例代码,读者可以更好地理解如何使用这些接口。最后,作者总结了`list`的特点和适用场景,并预告了后续关于`list`模拟实现的文章。
25 7
|
27天前
|
存储 编译器 C语言
【c++丨STL】vector的使用
本文介绍了C++ STL中的`vector`容器,包括其基本概念、主要接口及其使用方法。`vector`是一种动态数组,能够根据需要自动调整大小,提供了丰富的操作接口,如增删查改等。文章详细解释了`vector`的构造函数、赋值运算符、容量接口、迭代器接口、元素访问接口以及一些常用的增删操作函数。最后,还展示了如何使用`vector`创建字符串数组,体现了`vector`在实际编程中的灵活性和实用性。
53 4
|
29天前
|
C语言 C++ 容器
【c++丨STL】string模拟实现(附源码)
本文详细介绍了如何模拟实现C++ STL中的`string`类,包括其构造函数、拷贝构造、赋值重载、析构函数等基本功能,以及字符串的插入、删除、查找、比较等操作。文章还展示了如何实现输入输出流操作符,使自定义的`string`类能够方便地与`cin`和`cout`配合使用。通过这些实现,读者不仅能加深对`string`类的理解,还能提升对C++编程技巧的掌握。
68 5
|
29天前
|
存储 编译器 C语言
【c++丨STL】string类的使用
本文介绍了C++中`string`类的基本概念及其主要接口。`string`类在C++标准库中扮演着重要角色,它提供了比C语言中字符串处理函数更丰富、安全和便捷的功能。文章详细讲解了`string`类的构造函数、赋值运算符、容量管理接口、元素访问及遍历方法、字符串修改操作、字符串运算接口、常量成员和非成员函数等内容。通过实例演示了如何使用这些接口进行字符串的创建、修改、查找和比较等操作,帮助读者更好地理解和掌握`string`类的应用。
50 2
|
9天前
|
存储 对象存储 C++
C++ 中 std::array<int, array_size> 与 std::vector<int> 的深入对比
本文深入对比了 C++ 标准库中的 `std::array` 和 `std::vector`,从内存管理、性能、功能特性、使用场景等方面详细分析了两者的差异。`std::array` 适合固定大小的数据和高性能需求,而 `std::vector` 则提供了动态调整大小的灵活性,适用于数据量不确定或需要频繁操作的场景。选择合适的容器可以提高代码的效率和可靠性。
31 0
|
1月前
|
存储 算法 Linux
【c++】STL简介
本文介绍了C++标准模板库(STL)的基本概念、组成部分及学习方法,强调了STL在提高编程效率和代码复用性方面的重要性。文章详细解析了STL的六大组件:容器、算法、迭代器、仿函数、配接器和空间配置器,并提出了学习STL的三个层次,旨在帮助读者深入理解和掌握STL。
52 0
|
13天前
|
存储 编译器 C语言
【c++丨STL】vector模拟实现
本文深入探讨了 `vector` 的底层实现原理,并尝试模拟实现其结构及常用接口。首先介绍了 `vector` 的底层是动态顺序表,使用三个迭代器(指针)来维护数组,分别为 `start`、`finish` 和 `end_of_storage`。接着详细讲解了如何实现 `vector` 的各种构造函数、析构函数、容量接口、迭代器接口、插入和删除操作等。最后提供了完整的模拟实现代码,帮助读者更好地理解和掌握 `vector` 的实现细节。
26 0
|
1月前
|
存储 设计模式 C++
【C++】优先级队列(容器适配器)
本文介绍了C++ STL中的线性容器及其适配器,包括栈、队列和优先队列的设计与实现。详细解析了`deque`的特点和存储结构,以及如何利用`deque`实现栈、队列和优先队列。通过自定义命名空间和类模板,展示了如何模拟实现这些容器适配器,重点讲解了优先队列的内部机制,如堆的构建与维护方法。
35 0
|
2月前
|
存储 程序员 C++
C++常用基础知识—STL库(2)
C++常用基础知识—STL库(2)
85 5
|
2月前
|
存储 C++ 索引
【C++打怪之路Lv9】-- vector
【C++打怪之路Lv9】-- vector
26 1

热门文章

最新文章