赞
踩
1. queue 队列 : 是一个先进先出的容器 ; 下面是队列的使用流程 ;
2. 引入头文件 : 使用 queue 队列之前 , 必须先包含其头文件 , queue 队列是 STL 模板类中提供的容器 ;
//引入队列头文件 , 才能使用 queue 队列
//queue 队列 , 也是 STL 模板类中提供的容器
#include <queue>
3. 声明队列 : 格式 " queue<元素类型> 容器对象变量名称 " , 尖括号中声明了容器中存储的元素类型 , 如下代码表示该队列存储的是 int 类型元素 ;
//声明队列
queue<int> queue_1;
4. 添加元素 : 调用队列对象的 " push( 元素变量 ) " 向 queue 队列中添加元素 ;
//添加元素到队列中
queue_1.push(8);
queue_1.push(88);
5. 删除元素 : 调用 " pop() " 方法 , 将最后加入的元素弹出队列 ;
//将元素弹出队列
queue_1.pop();
6. 获取 queue 队列首元素 : 调用队列对象的 " front() " 方法可以获取队列首元素 ;
7. 获取 queue 队列尾元素 : 调用队列对象的 " back() " 方法可以获取队列最后的元素 ;
queue_1.front();
queue_1.back();
1. stack 栈 : 后进先出的容器 ;
2. 引入头文件 : 使用 queue 队列之前 , 必须先包含其头文件 , queue 队列是 STL 模板类中提供的容器 ;
//引入 stack 栈的头文件
#include <stack>
3. 声明 stack 栈 : 格式 " stack<元素类型> 容器对象变量名称 " , 尖括号中声明了容器中存储的元素类型 , 如下代码表示该 stack 栈存储的是 int 类型元素 ;
// III . stack 栈
//stack 栈 是后进先出的容器
stack<int> stack_1;
1. 声明优先级队列 : 声明时指定元素类型 , priority_queue 后尖括号中的类型就是其存储的元素类型 ;
//声明优先级队列
priority_queue<int> pq;
2. 添加元素 : 向优先级队列中添加元素 , 默认最大值在队首 ;
//其默认复制数值最大的在队首
pq.push(88);
pq.push(8);
pq.push(888);
3. 获取队首元素 : 调用优先级队列对象的 " top() " 方法 , 获取队首元素 , 将其打印出来 , 默认情况下 , 队首元素是最大值 ;
//获取队首元素 , 将其打印出来 , 应该是将最大的 888 打印到了控制台
//虽然 888 是最后添加进去的 , 但是其数值最大 , 被放在了首元素位置
int pq_top = pq.top();
cout << "打印 priority_queue 优先级队列的首元素 : pq.top() : " << pq.top() << endl;
4. 代码执行结果 :
打印 priority_queue 优先级队列的首元素 : pq.top() : 888
1. 排序算法 : 优先级队列默认情况下 , 会将最大值放在队首 , 是因为其默认的排序算法是 less<元素类型> , 上面的 priority_queue 优先级队列其排序算法类型是 less ;
2. 指定 priority_queue 优先级队列排序算法 : 这里指定队列中元素排序算法 , 将最大值放在队尾 , 最小值在队首 ;
//指定优先级队列最大值放在队尾
//参数 1 : 代表队列中元素的类型是 int 类型
//参数 2 : 代表优先级队列使用的内部容器 , 整个队列是基于 vector 容器的
//参数 3 : 设置排序行为 , 这个行为是在 STL 中定义的模板类
// less<int> : 是默认行为 , 最大的元素在前面
// greater<int> : 最小的在前面
priority_queue< int, vector<int> , greater<int> > pq_1;
pq_1.push(88);
pq_1.push(8);
pq_1.push(888);
cout << "打印 pq_1 优先级队列的首元素 : pq.top() : " << pq_1.top() << endl;
3. 代码执行结果 :
打印 pq_1 优先级队列的首元素 : pq.top() : 8
C++ 中定义的排序方法 : 其中的 less 结构体就是优先级队列中默认使用的排序方法 ;
// STRUCT TEMPLATE greater template <class _Ty = void> struct greater { // functor for operator> _CXX17_DEPRECATE_ADAPTOR_TYPEDEFS typedef _Ty first_argument_type; _CXX17_DEPRECATE_ADAPTOR_TYPEDEFS typedef _Ty second_argument_type; _CXX17_DEPRECATE_ADAPTOR_TYPEDEFS typedef bool result_type; constexpr bool operator()(const _Ty& _Left, const _Ty& _Right) const { // apply operator> to operands return _Left > _Right; } }; // STRUCT TEMPLATE less template <class _Ty = void> struct less { // functor for operator< _CXX17_DEPRECATE_ADAPTOR_TYPEDEFS typedef _Ty first_argument_type; _CXX17_DEPRECATE_ADAPTOR_TYPEDEFS typedef _Ty second_argument_type; _CXX17_DEPRECATE_ADAPTOR_TYPEDEFS typedef bool result_type; constexpr bool operator()(const _Ty& _Left, const _Ty& _Right) const { // apply operator< to operands return _Left < _Right; } };
1. 定义自定义类型 : 内部定义 age 成员变量 , 构造函数中设置该变量值 ;
//自定义容器
class Student {
public :
int age;
//声明构造方法 , 后面的 : age(age)
// 左侧的 age 表示给 age 成员赋值 , 右边的表示参数中的 age 值
Student(int age) : age(age){}
};
2. 自定义类型的排序方法定义 : 按照官方的定义方式定义排序方法 , 这里省略的模板方法相关内容 , 因为比较的就是 Student 类型对象 , 这里按照其 age 成员变量的大小进行比较 , age 成员变量最大的放在队首 ;
// Student 类对象排序方法定义
// 排序方式 : 左侧对象的 age 成员变量 , 大于右侧对象的 age 成员变量
struct StudentLess {
constexpr bool operator()(const Student& _Left, const Student& _Right) const {
return _Left.age < _Right.age;
}
};
3. 声明自定义类型容器队列 :
//自定义类型容器队列
// 注意此处必须指定 Student 对象之间的排序方式 , 否则编译时会报错
// 可以参考 less 和 greater 的实现
//自定义的排序方法 : StudentLess , 其会将 Student 对象的 age 成员变量大的排在前面
priority_queue< Student, vector<Student>, StudentLess > pq_student;
4. 加入 Student 对象 : 使用构造方法创建 Student 对象 , 并将对象放入队列中 , 打印出队首元素 ;
//向自定义类型容器队列中加入 3 个对象 , 使用构造函数生成对象
pq_student.push(Student(8));
pq_student.push(Student(18));
pq_student.push(Student(15));
cout << "打印 pq_student 优先级队列的首元素 : pq_student.top().age : " << pq_student.top().age << endl;
5. 执行结果 :
打印 pq_student 优先级队列的首元素 : pq_student.top().age : 18
关联式容器操作 : 关联式容器的操作 , 与序列式容器调用方法基本一致 ;
关联式容器访问方式 : 通过关键字保存和访问元素 , 如 Java 中的 Map , Set ;
1. Set 集合 : 内部是由红黑树实现的 , 每个节点都是一个元素 , 其元素不可重复 ;
2. 包含头文件 :
//引入 set 集合的头文件
#include <set>
3. 声明 set 集合 :
set<int> set_1 = {8 , 888 , 8888};
4. 插入元素 : 注意 set 集合中元素不能重复 , 如果插入重复的元素该操作是无效的 ;
//插入 18 , 集合中没有元素 18 , 此时插入成功
set_1.insert(18);
//插入 888 , 此时之前已经有了 888 元素 , set 集合不允许重复 , 本次插入失败
set_1.insert(888);
5. 插入解析 : 上面的两个操作中 , 集合中已经有了 888 元素 , 再次插入 888 元素 , 该操作是无效的 ;
6. 插入返回值解析 : insert 返回值是一个键值对 , 返回值类型 : pair<iterator, bool> ;
7. 删除元素 : 删除一个元素 , 其大小发生了改变 ;
//删除某个元素
set_1.erase(888);
//打印容器大小
cout << "打印 set_1 删除 888 容量大小 : set_1.size() : " << set_1.size() << endl;
8. 代码示例 :
// VI . set 集合 // Set : 集合 , 内部是由红黑树实现的 , 每个节点都是一个元素 , 其元素不可重复 set<int> set_1 = {8 , 888 , 8888}; //插入 18 , 集合中没有元素 18 , 此时插入成功 set_1.insert(18); //插入 888 , 此时之前已经有了 888 元素 , set 集合不允许重复 , 本次插入失败 set_1.insert(888); //insert 返回值是一个键值对 , 其键是一个迭代器 , // 值是 bool 类型 , 如果插入成功值为 true , 否则为 false // 返回值类型 : pair<iterator, bool> // 具体的返回值类型 : pair<set<int>::iterator, bool> //删除某个元素 set_1.erase(888); //打印容器大小 cout << "打印 set_1 删除 888 容量大小 : set_1.size() : " << set_1.size() << endl;
9. 执行结果 :
打印 set_1 删除 888 容量大小 : set_1.size() : 3
迭代器不是指针 , 是一个模板类 , 与指针行为一致 , 可以当做指针来用 ;
1. 迭代器使用 : 迭代器是一个模板类 ;
2. 获取迭代器 : 调用 vector 对象的 begin() 和 end() 方法 都可获取迭代器
vector<int> vector_iterator = {8 , 88 , 888};
//该迭代器指向容器中第 0 个元素
vector<int>::iterator iterator_begin = vector_iterator.begin();
//迭代器指向容器中最后一个元素的下一个元素 ,
// 注意 : 不是指向最后一个元素
vector<int>::iterator iterator_end = vector_iterator.end();
3. 使用迭代器进行遍历 , 打印 vector 中的元素;
for ( ; iterator_begin < iterator_end; iterator_begin ++ ) {
cout << "迭代器遍历 : " << *iterator_begin << endl;
}
4. 代码示例 :
// VII . 容器的遍历 //迭代器使用 : 迭代器是一个模板类 //获取迭代器 : 调用 vector 对象的 begin() 和 end() 方法 都可获取迭代器 vector<int> vector_iterator = {8 , 88 , 888}; //该迭代器指向容器中第 0 个元素 vector<int>::iterator iterator_begin = vector_iterator.begin(); //迭代器指向容器中最后一个元素的下一个元素 , // 注意 : 不是指向最后一个元素 vector<int>::iterator iterator_end = vector_iterator.end(); //使用迭代器进行遍历 , 打印 vector 中的元素 for ( ; iterator_begin < iterator_end; iterator_begin ++ ) { cout << "迭代器遍历 : " << *iterator_begin << endl; } //循环时尽量不修改容器大小 : 遍历时不能进行删除增加操作 , 否则会出错 ; //如果循环时修改大小 : 要根据实际情况进行操作 , 如删除操作 , // 如果将本元素删除 , 那么循环控制变量就不能自增 //迭代器不是指针 , 是一个模板类 , 与指针行为一致 , 可以当做指针来用 ;
5. 执行结果 :
迭代器遍历 : 8
迭代器遍历 : 88
迭代器遍历 : 888
1. 包含头文件 :
//引入 map 的头文件
#include <map>
2. map 特点 : map 中不能存在重复的 key ;
3. 声明 map : 直接初始化元素 ;
//声明 map 时 , 直接初始化元素
map<string, int> map_student = { {"Tom" , 6} , {"Jerry" , 2} };
4. 插入键值对 :
//插入一个键值对
map_student.insert({ "Trump" , 70 });
5. 访问对应键值对 :
//获取对应键的值 , 使用 map变量名称[键] 可以获取对应的值
map_student["Tom"] = 18;
6. 代码示例 :
// VIII . map 集合
//map 中不能存在重复的 key ;
//声明 map 时 , 直接初始化元素
map<string, int> map_student = { {"Tom" , 6} , {"Jerry" , 2} };
//插入一个键值对
map_student.insert({ "Trump" , 70 });
//获取对应键的值 , 使用 map变量名称[键] 可以获取对应的值
map_student["Tom"] = 18;
cout << "map_student[\"Tom\"] : " << map_student["Tom"] << endl;
7. 执行结果 :
map_student["Tom"] : 18
1. 容器代码示例 :
// 004_Container.cpp: 定义应用程序的入口点。 // #include "004_Container.h" //vector 是 C++ 中定义的模板类 #include <vector> //引入队列头文件 , 才能使用 queue 队列 //queue 队列 , 也是 STL 模板类中提供的容器 #include <queue> //引入 stack 栈的头文件 #include <stack> //引入 set 集合的头文件 #include <set> //引入 map 的头文件 #include <map> using namespace std; //自定义容器 class Student { public : int age; //声明构造方法 , 后面的 : age(age) // 左侧的 age 表示给 age 成员赋值 , 右边的表示参数中的 age 值 Student(int age) : age(age){} }; // Student 类对象排序方法定义 // 排序方式 : 左侧对象的 age 成员变量 , 大于右侧对象的 age 成员变量 struct StudentLess { constexpr bool operator()(const Student& _Left, const Student& _Right) const { return _Left.age < _Right.age; } }; int main() { cout << "Hello Container。" << endl; // I . vector 向量 ( vector , dequeue , list 调用方式基本一致 ) //vector 向量是一种支持快速随机访问的 , 连续存储元素的容器 //声明向量 vector<int> vector_1; //调用向量的构造方法 , 并传入一个 int 类型参数 //表示创建一个有 8 个 int 类型元素空间的向量 vector<int> vector_2(8); //表示创建有 8 个元素的向量 , 8 个元素的值都是 2 vector<int> vector_3(8 , 2); //初始化向量时 , 传入另一个向量 vector<int> vector_4(vector_3); // 2. 使用向量 : 增删查改 // ( 1 ) 增加元素 : 调用 push_back 方法 , 容器出入策略 , 后进先出 vector_1.push_back(8); vector_1.push_back(88); // ( 2 ) 查询元素 : // <1> 通过下标获取元素 // 这里的 [] 在 vector 中进行了运算符重载 cout << "通过下标获取 vector_1 第 0 个元素 : vector_1[0] : " << vector_1[0] << endl; // <2> 通过 at() 方法获取对应索引的元素 cout << "通过 at 方法获取 vector_1 第 0 个元素 : vector_1.at(0) : " << vector_1.at(0) << endl; // <3> 获取第一个元素 cout << "通过 front 方法获取 vector_1 第 1 个元素 : vector_1.front() : " << vector_1.front() << endl; // <4> 获取最后一个元素 cout << "通过 back 方法获取 vector_1 最后 1 个元素 : vector_1.back() : " << vector_1.back() << endl; // ( 4 ) 删除元素 : // <1> 调用 pop_back 方法 , 容器出入策略 , 后进先出 vector_1.pop_back(); //之前向 vector 中先后放入了 8 和 88 两个数 , // 然后删除了后一个元素 88 , 目前只剩下一个元素 8 // <2> 删除所有元素 , 这里只是清空元素内容为 0 vector_1.clear(); // <3> 删除指定位置区间的元素 , 这里只是清空元素内容为 0 // 第 1 个是删除的起始位置 , // 第 2 个参数是删除的结束位置 ; //删除从开始到结束的所有元素 vector_1.erase(vector_1.begin() , vector_1.end()); //关于删除元素内存说明 : // 删除若干元素后 , vector 的容量 , 即内存所占的空间是不会减小的 ; // 调用删除方法后 , 就不能在查询上述元素了 //打印 vector 容器容量大小 , 调用 vector 的 capacity() 方法即可获取其容量大小 // 这个容量大小是元素个数 , 不是内存字节数 cout << "打印 vector_1 容量大小 : vector_1.capacity() : " << vector_1.capacity() << endl; // ( 5 ) 改变容量 , 容器交换 , 这里使用一个容量为 0 的容器与之交换即可 //创建一个新的 vector , 此时其容量为 0 vector<int> vector_swap; //将创建的新的 vector_swap 与 vector_1 容器进行交换 vector_swap.swap(vector_1); cout << "打印 vector_1 交换后的容量大小 : vector_1.capacity() : " << vector_1.capacity() << endl; // II . queue 队列 //队列是一个先进先出的容器 //声明队列 queue<int> queue_1; //添加元素到队列中 queue_1.push(8); queue_1.push(88); //将元素弹出队列 queue_1.pop(); //获取首尾元素 queue_1.front(); queue_1.back(); // III . stack 栈 //stack 栈 是后进先出的容器 stack<int> stack_1; // IV . priority_queue 优先级队列 //声明优先级队列 priority_queue<int> pq; //其默认复制数值最大的在队首 pq.push(88); pq.push(8); pq.push(888); //获取队首元素 , 将其打印出来 , 应该是将最大的 888 打印到了控制台 //虽然 888 是最后添加进去的 , 但是其数值最大 , 被放在了首元素位置 int pq_top = pq.top(); cout << "打印 priority_queue 优先级队列的首元素 : pq.top() : " << pq.top() << endl; //指定优先级队列最大值放在队尾 //参数 1 : 代表队列中元素的类型是 int 类型 //参数 2 : 代表优先级队列使用的内部容器 , 整个队列是基于 vector 容器的 //参数 3 : 设置排序行为 , 这个行为是在 STL 中定义的模板类 // less<int> : 是默认行为 , 最大的元素在前面 // greater<int> : 最小的在前面 priority_queue< int, vector<int> , greater<int> > pq_1; pq_1.push(88); pq_1.push(8); pq_1.push(888); cout << "打印 pq_1 优先级队列的首元素 : pq.top() : " << pq_1.top() << endl; //自定义类型容器队列 // 注意此处必须指定 Student 对象之间的排序方式 , 否则编译时会报错 // 可以参考 less 和 greater 的实现 //自定义的排序方法 : StudentLess , 其会将 Student 对象的 age 成员变量大的排在前面 priority_queue< Student, vector<Student>, StudentLess > pq_student; //向自定义类型容器队列中加入 3 个对象 , 使用构造函数生成对象 pq_student.push(Student(8)); pq_student.push(Student(18)); pq_student.push(Student(15)); cout << "打印 pq_student 优先级队列的首元素 : pq_student.top().age : " << pq_student.top().age << endl; // V . 关联式容器 //操作 : 关联式容器的操作 , 与序列式容器调用方法基本一致 //访问方式 : 通过关键字保存和访问元素 , 如 Java 中的 Map , Set ; // VI . set 集合 // Set : 集合 , 内部是由红黑树实现的 , 每个节点都是一个元素 , 其元素不可重复 set<int> set_1 = {8 , 888 , 8888}; //插入 18 , 集合中没有元素 18 , 此时插入成功 set_1.insert(18); //插入 888 , 此时之前已经有了 888 元素 , set 集合不允许重复 , 本次插入失败 set_1.insert(888); //insert 返回值是一个键值对 , 其键是一个迭代器 , // 值是 bool 类型 , 如果插入成功值为 true , 否则为 false // 返回值类型 : pair<iterator, bool> // 具体的返回值类型 : pair<set<int>::iterator, bool> //删除某个元素 set_1.erase(888); //打印容器大小 cout << "打印 set_1 删除 888 容量大小 : set_1.size() : " << set_1.size() << endl; // VII . 容器的遍历 //迭代器使用 : 迭代器是一个模板类 //获取迭代器 : 调用 vector 对象的 begin() 和 end() 方法 都可获取迭代器 vector<int> vector_iterator = {8 , 88 , 888}; //该迭代器指向容器中第 0 个元素 vector<int>::iterator iterator_begin = vector_iterator.begin(); //迭代器指向容器中最后一个元素的下一个元素 , // 注意 : 不是指向最后一个元素 vector<int>::iterator iterator_end = vector_iterator.end(); //使用迭代器进行遍历 , 打印 vector 中的元素 for ( ; iterator_begin < iterator_end; iterator_begin ++ ) { cout << "迭代器遍历 : " << *iterator_begin << endl; } //循环时尽量不修改容器大小 : 遍历时不能进行删除增加操作 , 否则会出错 ; //如果循环时修改大小 : 要根据实际情况进行操作 , 如删除操作 , // 如果将本元素删除 , 那么循环控制变量就不能自增 /* vector<int> vector_iterator_delete = { 8 , 88 , 888 }; vector<int>::iterator iterator_begin_delete = vector_iterator_delete.begin(); vector<int>::iterator iterator_end_delete = vector_iterator_delete.end(); //遍历时删除元素 : 使用迭代器进行遍历 , 打印 vector 中的元素 , 遇到 888 元素 , 将其删除 for (; iterator_begin_delete < iterator_end_delete; iterator_begin_delete ++ ) { if (*iterator_begin_delete == 888) { cout << "迭代器遍历删除 ( 本次遍历删除该元素 ) : " << *iterator_begin_delete << endl; //如果元素值为 888 , 那么删除该元素 //iterator_begin_delete = vector_iterator_delete.erase(iterator_begin_delete); //iterator_begin_delete--; }else { cout << "迭代器遍历删除 ( 本次遍历没有删除 ) : " << *iterator_begin_delete << endl; } } */ //迭代器不是指针 , 是一个模板类 , 与指针行为一致 , 可以当做指针来用 ; // VIII . map 集合 //map 中不能存在重复的 key ; //声明 map 时 , 直接初始化元素 map<string, int> map_student = { {"Tom" , 6} , {"Jerry" , 2} }; //插入一个键值对 map_student.insert({ "Trump" , 70 }); //获取对应键的值 , 使用 map变量名称[键] 可以获取对应的值 map_student["Tom"] = 18; cout << "map_student[\"Tom\"] : " << map_student["Tom"] << endl; return 0; }
2. 执行结果 :
Hello Container。
通过下标获取 vector_1 第 0 个元素 : vector_1[0] : 8
通过 at 方法获取 vector_1 第 0 个元素 : vector_1.at(0) : 8
通过 front 方法获取 vector_1 第 1 个元素 : vector_1.front() : 8
通过 back 方法获取 vector_1 最后 1 个元素 : vector_1.back() : 88
打印 vector_1 容量大小 : vector_1.capacity() : 2
打印 vector_1 交换后的容量大小 : vector_1.capacity() : 0
打印 priority_queue 优先级队列的首元素 : pq.top() : 888
打印 pq_1 优先级队列的首元素 : pq.top() : 8
打印 pq_student 优先级队列的首元素 : pq_student.top().age : 18
打印 set_1 删除 888 容量大小 : set_1.size() : 3
迭代器遍历 : 8
迭代器遍历 : 88
迭代器遍历 : 888
map_student["Tom"] : 18
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。