[C++学习笔记] 7.1 STL —— vector容器

文章目录

  • 7. STL(Standard Template Library)
    • 7.0 STL基本概念
      • 7.0.1 容器container
      • 7.0.2 算法algorithm
      • 7.0.3 迭代器iterator
    • 7.1 vector容器
      • 7.1.1 vector构造操作
      • 7.1.2 vector赋值操作
      • 7.1.3 vector容量和大小
      • 7.1.4 vector插入和删除
      • 7.1.5 vector数据存取
      • 7.1.6 vector互换容器
      • 7.1.7 vector预留空间

7. STL(Standard Template Library)

  • C++的面向对象泛型编程思想,目的就是复用性的提升
  • 为了建立数据结构和算法的一套标准,诞生了STL(Standard Template Library,标准模板库)
  • STL中几乎所有代码都采用了类模板和函数模板,使其适用于各种数据类型

7.0 STL基本概念

STL大体分为六大组件,分别是:容器、算法、迭代器、仿函数、适配器(配接器)、空间配置器

  1. 容器:各种数据结构,如vector、list、deque、set、map等,用来存放数据。
  2. 算法:各种常用的算法,如sort、find、copy、for_each等
  3. 迭代器:扮演了容器与算法之间的胶合剂。
  4. 仿函数:行为类似函数,可作为算法的某种策略。
  5. 适配器:一种用来修饰容器或者仿函数或迭代器接口的东西。
  6. 空间配置器:负责空间的配置与管理。

7.0.1 容器container

容器: 置物之所也

STL容器就是将运用最广泛的一些数据结构(例如:数组, 链表,树, 栈, 队列, 集合, 映射表 等)实现出来

这些容器分为序列式容器关联式容器两种:

序列式容器:强调值的排序,序列式容器中的每个元素均有固定的位置。
关联式容器:二叉树结构,各元素之间没有严格的物理上的顺序关系

7.0.2 算法algorithm

算法: 问题之解法也

有限的步骤,解决逻辑或数学上的问题,这一门学科我们叫做算法(Algorithms)

算法分为:质变算法非质变算法

质变算法:是指运算过程中会更改区间内的元素的内容。例如拷贝,替换,删除等等

非质变算法:是指运算过程中不会更改区间内的元素内容,例如查找、计数、遍历、寻找极值等等

7.0.3 迭代器iterator

迭代器: 容器和算法之间粘合剂

提供一种方法,使之能够依序寻访某个容器所含的各个元素,而又无需暴露该容器的内部表示方式。

每个容器都有自己专属的迭代器

迭代器种类:

种类 功能 支持运算
输入迭代器 对数据的只读访问 只读,支持++、==、!=
输出迭代器 对数据的只写访问 只写,支持++
前向迭代器 读写操作,并能向前推进迭代器 读写,支持++、==、!=
双向迭代器 读写操作,并能向前和向后操作 读写,支持++、–,
随机访问迭代器 读写操作,可以以跳跃的方式访问任意数据,功能最强的迭代器 读写,支持++、–、[n]、-n、<、<=、>、>=

常用的容器中迭代器种类为双向迭代器,和随机访问迭代器

7.1 vector容器

连续存储的容器,动态数组,在堆上分配空间。

底层实现:动态数组,内存分配是一段连续的空间。

成倍容量增长:vector 增加(插入)新元素时,如果未超过当时的容量,则还有剩余空间,那么直接添加到最后(插入指定位置),然后调整迭代器。如果没有剩余空间了,则会重新配置原有元素个数的两倍空间,然后将原空间元素通过复制的方式初始化新空间, 再向新空间增加元素,最后析构并释放原空间,之前的迭代器会失效。 在VS下是1.5倍,在 GCC下是2倍。

在使用vector容器前先引入头文件#include

为了方便后续代码输出显示,这里定义一个输出函数printVector

#include
#include 
using namespace std;
void printVector(vector<int>& v) 
{
	for (vector<int>::iterator it = v.begin(); it != v.end(); it++) 
		cout << *it << " ";
	cout << endl;
}

7.1.1 vector构造操作

函数原型:

  • vector v; //采用模板实现类实现,默认构造函数
  • vector(v.begin(), v.end()); //将v[begin(), end())区间中的元素拷贝给本身。
  • vector(n, elem); //构造函数将n个elem拷贝给本身。
  • vector(const vector &vec); //拷贝构造函数。
// 构造操作
void test01() 
{
	vector<int> v1; 
	for (int i = 0; i < 10; i++)
		v1.push_back(i);
	printVector(v1);
    
	vector<int> v2(v1.begin(), v1.end());
	printVector(v2);
    
	vector<int> v3(10, 100);
	printVector(v3);
    
	vector<int> v4(v3);
    printVector(v4);
}

[C++学习笔记] 7.1 STL —— vector容器_第1张图片

7.1.2 vector赋值操作

函数原型:

  • vector& operator=(const vector &vec);//重载等号操作符

  • assign(beg, end); //将[beg, end)区间中的数据拷贝赋值给本身。

  • assign(n, elem); //将n个elem拷贝赋值给本身。

// 赋值操作
void test02()
{
	vector<int> v1;
	for (int i = 0; i < 10; i++)
		v1.push_back(i);
	printVector(v1);
    
	vector<int>v2;
	v2 = v1;
	printVector(v2);
    
	vector<int>v3;
	v3.assign(v1.begin(), v1.end());
    printVector(v3);

	vector<int>v4;
	v4.assign(10, 100);
    printVector(v4);
}

[C++学习笔记] 7.1 STL —— vector容器_第2张图片

7.1.3 vector容量和大小

函数原型:

  • empty(); //判断容器是否为空

  • capacity(); //容器的容量

  • size(); //返回容器中元素的个数

  • resize(int num); //重新指定容器的长度为num,若容器变长,则以默认值填充新位置。

    ​ //如果容器变短,则末尾超出容器长度的元素被删除。

  • resize(int num, elem); //重新指定容器的长度为num,若容器变长,则以elem值填充新位置。

    ​ //如果容器变短,则末尾超出容器长度的元素被删除

// 容量大小
void test03()
{
	vector<int> v1;
	for (int i = 0; i < 10; i++)
		v1.push_back(i);
    printVector(v1);

	if (v1.empty())
		cout << "v1为空" << endl;
	else
	{
		cout << "v1不为空" << endl;
		cout << "v1的容量 = " << v1.capacity() << endl;
		cout << "v1的大小 = " << v1.size() << endl;
	}

	//resize 重新指定大小 ,若指定的更大,默认用0填充新位置,可以利用重载版本替换默认填充
	v1.resize(15,10);
	printVector(v1);

	//resize 重新指定大小 ,若指定的更小,超出部分元素被删除
	v1.resize(5);
	printVector(v1);
}

[C++学习笔记] 7.1 STL —— vector容器_第3张图片

7.1.4 vector插入和删除

函数原型:

  • push_back(ele); //尾部插入元素ele
  • pop_back(); //删除最后一个元素
  • 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(); //删除容器中所有元素
// 插入和删除
void test04()
{
	vector<int> v1;
	// 尾插
	for (int i = 1; i < 6; i++)
		v1.push_back(i * 10);
	printVector(v1);
	// 尾删
	v1.pop_back();
	printVector(v1);
	// 插入
	v1.insert(v1.begin(), 100);
	printVector(v1);

	v1.insert(v1.begin(), 2, 1000);
	printVector(v1);

	//删除
	v1.erase(v1.begin());
	printVector(v1);

	//清空
	v1.erase(v1.begin(), v1.end());
	v1.clear();
	printVector(v1);
}

[C++学习笔记] 7.1 STL —— vector容器_第4张图片

7.1.5 vector数据存取

函数原型:

  • at(int idx); //返回索引idx所指的数据
  • operator[]; //返回索引idx所指的数据
  • front(); //返回容器中第一个数据元素
  • back(); //返回容器中最后一个数据元素
void test05()
{
	vector<int>v1;
	for (int i = 0; i < 10; i++)
		v1.push_back(i);

	for (int i = 0; i < v1.size(); i++)
		cout << v1[i] << " ";
	cout << endl;

	for (int i = 0; i < v1.size(); i++)
		cout << v1.at(i) << " ";
	cout << endl;

	cout << "v1的第一个元素为: " << v1.front() << endl;
	cout << "v1的最后一个元素为: " << v1.back() << endl;
}

[C++学习笔记] 7.1 STL —— vector容器_第5张图片

7.1.6 vector互换容器

函数原型:

  • swap(vec); // 将vec与本身的元素互换
void test06()
{
	vector<int>v1;
	for (int i = 0; i < 10; i++)
		v1.push_back(i);
	printVector(v1);

	vector<int>v2;
	for (int i = 10; i > 0; i--)
		v2.push_back(i);
	printVector(v2);

	// 互换容器
	cout << "互换后" << endl;
	v1.swap(v2);
	printVector(v1);
	printVector(v2);
}

[C++学习笔记] 7.1 STL —— vector容器_第6张图片

7.1.7 vector预留空间

减少vector在动态扩展容量时的扩展次数

函数原型:

  • reserve(int len);//容器预留len个元素长度,预留位置不初始化,元素不可访问。
void test07()
{
    vector<int> v;
    v.reserve(50000); // 如果数据量较大,可以一开始利用reserve预留空间
    int num = 0;
    int *p = NULL;
    for (int i = 0; i < 100000; i++)
    {
        v.push_back(i);
        if (p != &v[0])
        {
            p = &v[0];
            num++;
        }
    }
    cout << "num:" << num << endl;
}

[C++学习笔记] 7.1 STL —— vector容器_第7张图片

你可能感兴趣的