C++ STL (Standard Template Library标准模板库)
是通用类模板和算法的集合,它提供给程序员一些标准的数据结构的实现如
queues(队列), lists(链表), 和 stacks(栈)等.
C++ STL 提供给程序员以下三类数据结构的实现:
顺序结构
C++ Vectors
C++ Lists
C++ Double-Ended Queues
容器适配器
C++ Stacks
C++ Queues
C++ Priority Queues
联合容器
C++ Bitsets
C++ Maps
C++ Multimaps
C++ Sets
C++ Multisets
程序员使用复杂数据结构的最困难的部分已经由STL完成.
如果程序员想使用包含int数据的stack, 他只要写出如下的代码:
stack myStack;
接下来, 他只要简单的调用 push() 和 pop() 函数来操作栈.
借助 C++ 模板的威力, 他可以指定任何的数据类型,不仅仅是int类型.
STL stack实现了栈的功能,而不管容纳的是什么数据类型.
1.Vectors
Vectors 包含着一系列连续存储的元素,其行为和数组类似。
访问Vector中的任意元素或从末尾添加元素都可以在常量级时间复杂度内完成,
而查找特定值的元素所处的位置或是在Vector中插入元素则是线性时间复杂度。
Vectors 本质上是一个动态数组。
查找、尾插方便
任意位置插入删除 麻烦。
1.1使用Vectors要求包含头文件
#include <vector>
1.2实例化对象
vector my_vec;//创建一个空的vector
或:
vector my_vec(5,100);//创建一个vector并且插入5个100 ---一般不使用这种方式
1.3常用函数
push_back() 在Vector最后添加一个元素
size() 返回Vector元素数量的大小
clear() 清空所有元素
empty() 判断Vector是否为空(返回true时为空)
例:
#include <iostream>
#include <vector>
using namespace std;
int main(int argc, const char *argv[])
{
vector<int> my_vec;
cout<<my_vec.size()<<endl;
if(my_vec.empty()){
cout<<"vector 空"<<endl;
}else{
cout<<"vector 非空"<<endl;
}
my_vec.push_back(10);
my_vec.push_back(20);
my_vec.push_back(30);
my_vec.push_back(40);
my_vec.push_back(50);
cout<<"-----------------"<<endl;
cout<<my_vec.size()<<endl;
if(my_vec.empty()){
cout<<"vector 空"<<endl;
}else{
cout<<"vector 非空"<<endl;
}
cout<<"-----------------"<<endl;
for(int i = 0; i < my_vec.size(); i++){
//cout<<my_vec[i]<<" ";
cout<<my_vec.at(i)<<" ";//两种访问方式都可以
}
cout<<endl;
cout<<"-----------------"<<endl;
my_vec.clear();
cout<<my_vec.size()<<endl;
if(my_vec.empty()){
cout<<"vector 空"<<endl;
}else{
cout<<"vector 非空"<<endl;
}
return 0;
}
1.4迭代器 iterator
1.迭代器是广义上的指针,起操作和行为与指针非常类似。
每种数据结构都有自己的迭代器,是嵌套在类模板中的。
2.迭代器使用
使用是 可以通过 模板名和作用域限定符来区分
3.如使用vector 的迭代器,可以按下面方式指定
vector::iterator my_iter;
vector::iterator my_iter = my_vec.begin();//可以用这种方式初始化
#include <iostream>
#include <vector>
using namespace std;
int main(int argc, const char *argv[])
{
vector<int> my_vec;
vector<int>::iterator my_iter;
my_vec.push_back(10);
my_vec.push_back(20);
my_vec.push_back(30);
my_vec.push_back(40);
my_vec.push_back(50);
for(my_iter = my_vec.begin(); my_iter!=my_vec.end(); my_iter++){
cout<<*my_iter<<" ";
}
cout<<endl;
return 0;
}
1.5重要方法:
iterator erase( iterator loc );
iterator erase( iterator start, iterator end );
erase函数要么删作指定位置loc的元素,要么删除区间[start, end)的所有元素.
返回值是指向删除的最后一个元素的下一位置的迭代器.
#include <iostream>
#include <vector>
using namespace std;
int main(int argc, const char *argv[])
{
vector<int> my_vec;
vector<int>::iterator my_iter;
my_vec.push_back(1);
my_vec.push_back(3);
my_vec.push_back(3);
my_vec.push_back(3);
my_vec.push_back(3);
my_vec.push_back(2);
/*
for(my_iter = my_vec.begin(); my_iter!=my_vec.end(); my_iter++){
if(*my_iter%3 == 0){
my_vec.erase(my_iter);
}
}
//这种方式删除元素是错误的,因为erase后已经指向下一元素了,不应该再++l
//正确的写法应该是下面这种
*/
for(my_iter = my_vec.begin(); my_iter!=my_vec.end(); ){
if(*my_iter%3 == 0){
my_vec.erase(my_iter);
}else{
my_iter++;
}
}
cout<<endl;
cout<<"------------------"<<endl;
for(my_iter = my_vec.begin(); my_iter!=my_vec.end(); my_iter++){
cout<<*my_iter<<" ";
}
cout<<endl;
return 0;
}
例2:区间删除 [ ) 左闭右开区间
#include <iostream>
#include <vector>
using namespace std;
int main(int argc, const char *argv[])
{
vector<int> my_vec;
vector<int>::iterator my_iter1;
vector<int>::iterator my_iter2;
for(int i = 1; i <= 30; i++){
my_vec.push_back(i);
}
//想删除 10 ~ 20
for(my_iter1 = my_vec.begin(); *my_iter1 != 10; my_iter1++){}//找元素10 的迭代器
for(my_iter2 = my_vec.begin(); *my_iter2 != 21; my_iter2++){}//找元素21 的迭代器
my_vec.erase(my_iter1,my_iter2);
cout<<"------------------"<<endl;
for(my_iter1 = my_vec.begin(); my_iter1!=my_vec.end(); my_iter1++){
cout<<*my_iter1<<" ";
}
cout<<endl;
return 0;
}
练习:
使用vector 和其迭代器实现打印如下图案
ABCDEF
BCDEF
CDEF
DEF
EF
F
#include <iostream>
using namespace std;
#include <vector>
int main(void)
{
vector<char> my_vec;
for(char i = 'A'; i <= 'F'; i++){
my_vec.push_back(i);
}
vector<char>::iterator my_iter = my_vec.begin();
for (int i = 0; i < 6; i++) {
for (my_iter = my_vec.begin(); my_iter != my_vec.end(); my_iter++) {
cout << *my_iter << " ";
}
my_iter = my_vec.begin();
my_vec.erase(my_iter);
cout << endl;
}
return 0;
}
2.Lists
Lists将元素按顺序储存在链表中. 与 向量(vectors)相比,
它允许快速的插入和删除,但是随机访问却比较慢.
2.1要求
#include <list>
2.2实例化对象
list my_list;//创建一个空的list
2.3常用函数
push_back() 在list最后添加一个元素
push_front() 在list最开始添加一个元素
pop_back() 在list最后删除一个元素
pop_front() 在list最开始删除一个元素
size() 返回list元素数量的大小
clear() 清空所有元素
empty() 判断list是否为空(返回true时为空)
reverse() 把list的元素倒转
sort() 给list排序 --默认升序
#include <iostream>
using namespace std;
#include <list>
int main(int argc, const char *argv[])
{
list<int> my_list;
list<int>::iterator my_iter;
if(my_list.empty() == true){
cout<<"list 为空"<<endl;
}else{
cout<<"list 为非空"<<endl;
}
my_list.push_back(30);
my_list.push_back(20);
my_list.push_back(10);
my_list.push_back(40);
cout<<my_list.size()<<endl;
for(my_iter = my_list.begin(); my_iter != my_list.end(); my_iter++){
cout<<*my_iter<<" ";
}
cout<<endl;
cout<<"---------------------"<<endl;
my_list.sort();
for(my_iter = my_list.begin(); my_iter != my_list.end(); my_iter++){
cout<<*my_iter<<" ";
}
cout<<endl;
cout<<"---------------------"<<endl;
my_list.reverse();
for(my_iter = my_list.begin(); my_iter != my_list.end(); my_iter++){
cout<<*my_iter<<" ";
}
cout<<endl;
return 0;
}
3.Maps
3.1map是一个二叉树存储的容器
3.2map是一种关联式容器,里面存储的都是键值对
3.3map中key值是唯一的,不支持指定位置插入
3.4使用要求
#include <map>
3.5定义map对象
map<int,string> my_map1;
map<int,int> my_map2;
3.6常用的函数
insert() 插入元素
find() 查找一个元素
#include <iostream>
using namespace std;
#include <map>
int main(int argc, const char *argv[])
{
map<int,string> my_map;
map<int,string>::iterator my_iter;
my_map.insert(pair<int,string> (1001,"小明"));
my_map.insert(pair<int,string> (1002,"小红"));
my_map.insert(pair<int,string> (1003,"小钱"));
//这种方式每次插入都要实例化一个 pair 对象,代码写着啰嗦 一般不用
pair<int,string> temp_pair(1004,"小李");
my_map.insert(temp_pair);
//也可以用下面的方法
// my_map[key] = value;
my_map[1005] = "小张";
for(my_iter=my_map.begin();my_iter!=my_map.end();my_iter++){
cout<<"key:"<<(*my_iter).first<<" "<<"value:"<<(*my_iter).second<<endl;
}
cout<<"----------------"<<endl;
my_iter = my_map.find(1002);
if(my_iter != my_map.end()){
cout<<"key:"<<(*my_iter).first<<" "<<"value:"<<(*my_iter).second<<endl;
}
return 0;
}