# 一、Vector容器
# 1.1基本概念
vector数据结构和数组非常类似,也称为单端数组
vector与普通数组的区别在于:数组是静态空间,然而vector是可以动态扩展
- 动态扩展:并不是在原有空间之后续接新空间,而是找到更大的内存空间然后将原始数据拷贝到新空间然后释放原有空间
# 1.2vector构造函数
vector<T> v;
采用模板实现类实现,默认构造函数victor(v.begin(), v.end());
将v[begin(), end()]区间中的元素拷贝给本身victor(n, elem);
构造函数将n个elem拷贝给自身vector(const vector &vec);
拷贝构造函数
#include "iostream"
#include "vector"
using namespace std;
void printVector(vector<int> &vec) {
for (vector<int>::iterator it = vec.begin(); it != vec.end(); it++) {
cout << *it << " ";
}
cout << endl;
}
int main() {
// 默认构造
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);
// n个elem方式构造
vector<int> v3(10, 100);
printVector(v3);
// 拷贝构造
vector<int> v4(v3);
printVector(v4);
}
# 1.3vector赋值操作
vector &operator = (const vector &vec);
重载等号操作符assign(beg, end);
将[beg, end]区间中的数据拷贝赋值给本身assign(n, elem);
将n个elem拷贝赋值给本身
#include "iostream"
#include "vector"
using namespace std;
void printVector(vector<int> &vec) {
for (vector<int>::iterator it = vec.begin(); it != vec.end(); it++) {
cout << *it << " ";
}
cout << endl;
}
int main() {
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);
}
# 1.4vector容量操作
empty()
判断是否为空capacity()
容器的容量size()
返回容器中元素的个数resize(int num)
重新制定容量的长度为num,如果变长则用默认值0填充新位置,如果变短,超出的部分元素被删除resize(int num, elem)
重新制定容量长度为num,如果变长则用elem值填充新位置,如果变短,超出的部分元素被删除
//
// Created by Jacob Lee on 2021/12/29.
//
#include "iostream"
#include "vector"
using namespace std;
void printVector(vector<int> &vec) {
for (vector<int>::iterator it = vec.begin(); it != vec.end(); it++) {
cout << *it << " ";
}
cout << endl;
}
int main() {
vector<int> v1;
for (int i = 0; i < 10; ++i) {
v1.push_back(i);
}
printVector(v1);
if (v1.empty()) {
cout << "空" << endl;
} else {
cout << "非空" << endl;
}
int cap = v1.capacity();
cout << cap << endl;
int size = v1.size();
cout << size << endl;
// 重新制定大小
v1.resize(15);
printVector(v1);
// 重新制定大小(重载)
v1.resize(20, 1);
printVector(v1);
}
# 1.5vector插入删除
push_back(ele)
在尾部插入元素pop_back()
删除最后一个元素insert(const_iterator pos, ele)
迭代器指向位置pos插入元素eleinsert(const_iterator pos, int count, ele)
迭代器指向位置pos插入count个元素eleerase(const_iterator pos)
删除迭代器指向的元素erase(const_iterator pos, const_iterator end)
删除迭代器从start到end之间的元素clear()
删除容器中所有元素
# 1.6数据存取
at(int idx)
获取索引idx位置数据operator[idx]
获取索引idx位置数据front()
返回容器第一个数据back()
返回容器最后一个数据
# 1.7容器互换
swap(vec)
将vec与本身的元素互换
#include "iostream"
#include "vector"
using namespace std;
void printVector(vector<int> &vec) {
for (vector<int>::iterator it = vec.begin(); it != vec.end(); it++) {
cout << *it << " ";
}
cout << endl;
}
int main() {
vector<int> v1;
for (int i = 0; i < 10; ++i) {
v1.push_back(i);
}
printVector(v1);
vector<int> v2;
for (int i = 10; i < 20; ++i) {
v2.push_back(i);
}
printVector(v2);
v1.swap(v2);
printVector(v1);
printVector(v2);
}
巧妙地使用swap可以收缩内存空间
# 1.8vector预留空间
用于减少vector在动态扩展容量时的扩展次数
reserve(int len)
容器中预留len个元素长度,预留的位置不可以进行初始化,元素不可以访问
# 二、Deque容器
# 2.1基本概念
双端数组,可以在头端进行插入删除操作
deque与vector的区别:
- vector对于头部的插入删除效率太低了,数据量越大,效率越低
- deque对头部的插入删除速度会比vector快
- vector访问元素的速度会比deque快,这和两者的内部实现有关
deque的内部实现原理:
- deque内部有一个中控器,维护着每一段缓冲区中的内容,缓冲区中存放的是真实的数据
- 中控器维护的是每一个缓冲区的地址,使得使用deque时像一片连续的内存空间
deque容器的迭代器也是支持随机访问的
# 2.2deque构造函数
deque<T>
默认构造函数deque(beg, end)
构造函数将[beg, end)区间中的元素拷贝给自身deque(n, elem)
构造函数将n个elem元素拷贝给自身deque(const deque &deq)
拷贝构造函数
#include "iostream"
#include "deque"
using namespace std;
void printDeque(const deque<int> &deq) {
for (deque<int>::const_iterator it = deq.begin(); it != deq.end(); it++) {
cout << * it << " ";
}
cout << endl;
}
int main() {
deque<int> d1;
for (int i = 0; i < 10; ++i) {
d1.push_back(i);
}
printDeque(d1);
deque<int> d2(d1.begin(), d1.end());
printDeque(d2);
deque<int> d3(10, 100);
printDeque(d3);
deque<int> d4(d3);
printDeque(d4);
}
# 2.3deque赋值操作
deque& operator = (const deque &deq);
重载等号操作符assign(beg, end)
将[beg, end]区间中的数据拷贝赋值给本身assign(n, elem)
将n个elem拷贝赋值给本身
# 2.4deque大小操作
empty()
判断是否为空size()
返回容器中元素的个数resize(int num)
重新制定容量的长度为num,如果变长则用默认值0填充新位置,如果变短,超出的部分元素被删除resize(int num, elem)
重新制定容量长度为num,如果变长则用elem值填充新位置,如果变短,超出的部分元素被删除
# 2.5插入和删除
两端插入操作:
push_back(elem)
在容器尾部添加一个元素push_front(elem)
在容器头部添加一个元素pop_back()
删除容器最后一个数据pop_front()
删除容器第一个数据
指定位置操作:
insert(pos, elem)
在pos位置插入一个elem元素的拷贝,返回新数据的位置insert(pos, n, elem)
在pos位置插入n个elem数据,无返回值insert(pos, beg, end)
在pos位置插入[beg, end]区间的数据,无返回值clear()
清空容器的所有元素erase(beg, end)
删除[beg, end]区间的数据,返回下一个数据的位置erase(pos)
删除pos位置的数据,返回下一个数据的位置
# 2.6数据存取
at(int idx)
获取索引idx位置数据operator[idx]
获取索引idx位置数据front()
返回容器第一个数据back()
返回容器最后一个数据
# 2.7deque排序
利用算法实现对deque容器进行排序
算法:sort(iterator beg, iterator end)
对beg和end区间内所有元素进行排序
# 三、简单案例
#include "iostream"
#include "string"
#include "vector"
#include "deque"
#include "algorithm"
#include "ctime"
using namespace std;
class Person {
public:
string m_Name;
int m_Score;
// 构造函数
Person(string name, int score): m_Name(name), m_Score(score) {}
};
// 创建选手
void createPerson(vector<Person> &v) {
string nameSpeed = "ABCDE";
for (int i = 0; i < 5; i++) {
string name = "Player";
name += nameSpeed[i];
// cout << name << endl;
int score = 0;
Person p(name, score);
// 将创建的对象放入容器中
v.push_back(p);
}
}
// 测试打印
void printVector(const vector<Person> &v) {
for (vector<Person>::const_iterator it = v.begin(); it != v.end(); it++) {
cout << "选手" << it->m_Name << "的分数是:" << it->m_Score << endl;
}
}
// 打分函数
void setScore(vector<Person> &v) {
for (vector<Person>::iterator it = v.begin(); it != v.end(); it++) {
// 存放分数至deque容器中
deque<int> d;
for (int i = 0; i < 10; i++) {
// 给定随机分
int score = rand() % 41 + 60;
d.push_back(score);
}
sort(d.begin(), d.end());
// 去除最高分最低分
d.pop_back();
d.pop_front();
// 取平均分
int sum = 0;
for (deque<int>::iterator dit = d.begin(); dit != d.end(); dit++) {
sum += *dit;
}
int avg = sum / d.size();
// 将平均分赋值给选手
it->m_Score = avg;
}
}
int main() {
// 添加随机数种子
srand((unsigned int) time(NULL));
// 创建选手
vector<Person> v;
// 给选手打分
createPerson(v);
setScore(v);
// 显示最后得分
printVector(v);
return 0;
}