C++STL简介

百度的说法:STL是Standard Template Library的简称,中文名标准模板库,STL可分为容器(containers)、迭代器(iterators)、空间配置器(allocator)、配接器(adapters)、算法(algorithms)、仿函数(functors)六个部分。我这篇文章主要将STL分为三类:容器、算法、迭代器

1、容器:

顺序容器:保存元素的序列
Vector 向量:分配在连续内存,动态增长的数组,快速访问任意元素(常量时间),能在末端快速插入或删除元素(摊还常量时间,即大部分插入操作都是在常量时间内完成),但元素中间插入或删除元素较慢(线性时间)。
List 双向链表:不一定为连续内存,支持动态增长,随机访问元素较慢(线性时间),找到元素后插入或删除较快(常量时间)
Forward_list(仅限C++11) 单向链表:内存需求比list小,只支持向前迭代
Deque 双端队列:类似vector,快速的元素访问(常量时间),两端快速插入删除(摊还常量时间),序列中间插入和删除较慢(线性时间)
Array :标准数组替代品,能知道自己的大小,不会自动转换为指针类型,不提供插入删除操作,大小固定,允许在堆栈上分配内存,元素的访问速度极快(常量时间)
关联容器:
排序或有序关联容器: 关联了键和值,并对元素排序
set 集合:每个元素都是唯一,集合中每个元素最多有一个实例,元素按照一定顺序保存,提供了对数时间的插入、删除和查找操作,即插入删除比vecto快,比list慢,查找比list快,比vector慢。 需要保证元素顺序,插入/删除和查找性能接近时,优先使用set
Multiset :允许重复元素
Map 映射:保存键值对,按照键值的顺序保存元素,例如书号是键值,书名是对象值,其他方面,set和map一致,需要关联键值则使用map,否则使用set;map可以作为关联数组使用
Multimap:允许重复键的map
无序关联容器/哈希表:
Unordered_set:
Unordered_map:
Unordered_multiset:
Unordered_multimap:
前两个定义于,后两个定义于 ,行为上与对应有序关联容器类似,只是不对元素进行排序,无序关联容器的插入、删除和查找操作以平均常量时间完成,最糟糕为线性时间,查找元素的速度比普通map和set快很多,元素数量特别大时尤其如此

容器适配器:构建在某种标准顺序容器(vector、list或deque)上的简单接口
Queue 队列:标准先入先出,一端插入(摊还常量时间)、另一端取出元素(常量时间)
Priority_queue:优先队列,元素按照优先级从队列中移除,插入和删除比queue快,可视为带有意外的队列
Stack 栈:标准先入后出,只有顶部对象是可见的,提供快速的插入删除(常量时间)

其他:

Bitset:可视为bool值序列,有固定大小,不支持迭代器
bitsetvarm (M)
其中varm为变量名。
N表示该类型在内存中占的位数,是二进制。
M表示变量varm的初始值。
bitset 有三种声明方式。在缺省定义中,我们只需简单地指明位向量的长度。例如:
bitset< 32 > bitvec;
声明了一个含有32 个位的bitset,对象位的顺序从0 到31。缺省情况下所有的位都被初始化为0 。
当bitset对象的一位或多个位被设置为1 时any()返回true
如果bitset 对象的所有位都被设置为0 ,则none()操作返回true
count()操作返回被设置为1的位的个数
用set()操作或者下标操作符来设置某个单独的位,
例如:用整值类型将第27 位设置为1, 我们这样写
quiz1 |= 1<<27;
而用bitset 来做我们可以写
quizl[ 27 ] = 1;

quiz1.set( 27 );
要使用bitset 类我们必须包含相关的头文件
include < bitset>
,测试某个单独的位是否为1 也有两种方式
test()操作。用位置做参数,返回true或false, bitvec.test( 0 )或bitvec[0];
将某个单独的位设置为0 ,我们可以用reset()或下标操作符
flip()操作翻转整个bitset 对象或一个独立的位
bitvec.flip( 0 ); // 翻转第一位
bitvec[0].flip(); // 也是翻转第一位
bitvec.flip(); // 翻转所有的位的值
String 从技术角度看也是容器,可视为字符向量

接着说算法:

2、算法

按是否修改容器中的内容和排序及相关操作,给标准库中的算法函数进行分类
非修改性序列操作(12个)
循环 for_each() 对序列中的每个元素执行某操作
查找 find() 在序列中找出某个值的第一次出现的位置
find_if() 在序列中找出符合某谓词的第一个元素
find_end() 在序列中找出一子序列的最后一次出现的位置
find_first_of() 在序列中找出第一次出现指定值集中之值的位置
adjacent_find() 在序列中找出相邻的一对值
计数 count() 在序列中统计某个值出现的次数
count_if() 在序列中统计与某谓词匹配的次数
比较 mismatch() 找出两个序列相异的第一个元素
equal() 两个序列中的对应元素都相同时为真
搜索 search() 在序列中找出一子序列的第一次出现的位置
search_n() 在序列中找出一值的连续n次出现的位置

修改性序列操作(27个)
复制 copy() 从序列的第一个元素起进行复制
copy_backward() 从序列的最后一个元素起进行复制
交换 swap() 交换两个元素
swap_ranges() 交换指定范围的元素
iter_swap() 交换由迭代器所指的两个元素
变换 transform() 将某操作应用于指定范围的每个元素
替换 replace() 用一个给定值替换一些值
replace_if() 替换满足谓词的一些元素
replace_copy() 复制序列时用一给定值替换元素
replace_copy_if() 复制序列时替换满足谓词的元素
填充 fill() 用一给定值取代所有元素
fill_n() 用一给定值取代前n个元素
生成 generate() 用一操作的结果取代所有元素
generate_n() 用一操作的结果取代前n个元素
删除 remove() “删除”具有给定值的元素,实际上是将元素放在序列末尾,真正删除需要erase()算法
remove_if() 删除满足谓词的元素
remove_copy() 复制序列时删除具有给定值的元素
remove_copy_if() 复制序列时删除满足谓词的元素
唯一 unique() “删除”相邻的重复元素,实际上是将元素放在序列末尾,真正删除需要erase()算法,函数返回值是去重之后的尾地址,如
int num[10]={1,1,2,2,2,3,4,5,5,5}; int ans=unique(num,num+10)-num,ans是去重后的数组长度5【去重后的尾地址-数值起始地址】
unique_copy() 复制序列时删除相邻的重复元素
反转 reverse() 反转元素的次序
reverse_copy() 复制序列时反转元素的次序
环移 rotate() 循环移动元素
rotate_copy() 复制序列时循环移动元素
随机 random_shuffle() 采用均匀分布来随机移动元素
划分 partition() 将满足某谓词的元素都放到前面
stable_partition() 将满足某谓词的元素都放到前面并维持原顺序

序列排序及相关操作(27个)
排序 sort() 以很好的平均效率排序
stable_sort() 排序,并维持相同元素的原有顺序
partial_sort() 将序列的前一部分排好序
partial_sort_copy() 复制的同时将序列的前一部分排好序
第n个元素 nth_element() 将第n各元素放到它的正确位置
二分检索 lower_bound() 找到大于等于某值的第一次出现
upper_bound() 找到大于某值的第一次出现
equal_range() 找到(在不破坏顺序的前提下)可插入给定值的最大范围
binary_search() 在有序序列中确定给定元素是否存在
归并 merge() 归并两个有序序列
inplace_merge() 归并两个接续的有序序列
有序结构上的集合操作 includes() 一序列为另一序列的子序列时为真
set_union() 构造两个集合的有序并集
set_intersection() 构造两个集合的有序交集
set_difference() 构造两个集合的有序差集
set_symmetric_difference() 构造两个集合的有序对称差集(并-交)
堆操作 push_heap() 向堆中加入元素
pop_heap() 从堆中弹出元素
make_heap() 从序列构造堆
sort_heap() 给堆排序
最大和最小 min() 两个值中较小的
max() 两个值中较大的
min_element() 序列中的最小元素
max_element() 序列中的最大元素
词典比较 lexicographical_compare() 两个序列按字典序的第一个在前
排列生成器 next_permutation() 按字典序的下一个排列
prev_permutation() 按字典序的前一个排列

3、迭代器

迭代器:
STL通过迭代器模式提供了访问容器元素使用的泛型抽象,每个容器都提供了容器特定的迭代器,迭代器实际上是增强的智能指针,这些指针知道如何遍历容器中的元素,所有迭代器都遵循c++标准中定义的特定接口,附容易理解的代码:
代码原帖;https://www.cnblogs.com/shiyangxt/archive/2008/09/11/1289493.html 强烈推荐大家去看看!

#include <iostream>
#include <list>

using namespace std;
typedef list<int> INTLIST;

//从前向后显示list队列的全部元素
void put_list(INTLIST list, char *name)
{
    INTLIST::iterator plist;

    cout << "The contents of " << name << " : ";
    for(plist = list.begin(); plist != list.end(); plist++)
        cout << *plist << " ";
    cout<<endl;
}

//测试list容器的功能
int main(){
//list1对象初始为空
    INTLIST list1;   
    //list2对象最初有10个值为6的元素 
    INTLIST list2(10,6); 
    //list3对象最初有9个值为6的元素,用链表给链表赋值 
    INTLIST list3(list2.begin(),--list2.end()); 

    //声明一个名为i的双向迭代器
    INTLIST::iterator i;

    //从前向后显示各list对象的元素
    put_list(list1,"list1");
    put_list(list2,"list2");
    put_list(list3,"list3");

//从list1序列后面添加两个元素
list1.push_back(2);
list1.push_back(4);
cout<<"list1.push_back(2) and list1.push_back(4):"<<endl;
    put_list(list1,"list1");

//从list1序列前面添加两个元素
list1.push_front(5);
list1.push_front(7);
cout<<"list1.push_front(5) and list1.push_front(7):"<<endl;
    put_list(list1,"list1");

//在list1序列中间插入数据3个9 
list1.insert(++list1.begin(),3,9);
cout<<"list1.insert(list1.begin(),3,9):"<<endl;
    put_list(list1,"list1");

//测试引用类函数
cout<<"list1.front()="<<list1.front()<<endl;
cout<<"list1.back()="<<list1.back()<<endl;

//从list1序列的前后各移去一个元素
list1.pop_front();
list1.pop_back();
cout<<"list1.pop_front() and list1.pop_back():"<<endl;
    put_list(list1,"list1");

//清除list1中的第2个元素
list1.erase(++list1.begin());
cout<<"list1.erase(++list1.begin()):"<<endl;
    put_list(list1,"list1");

//对list2赋值并显示
list2.assign(8,1);
cout<<"list2.assign(8,1):"<<endl;
    put_list(list2,"list2");

//显示序列的状态信息
cout<<"list1.max_size(): "<<list1.max_size()<<endl;
cout<<"list1.size(): "<<list1.size()<<endl;
cout<<"list1.empty(): "<<list1.empty()<<endl;

//list序列容器的运算
    put_list(list1,"list1");
    put_list(list3,"list3");
cout<<"list1>list3: "<<(list1>list3)<<endl;
cout<<"list1<list3: "<<(list1<list3)<<endl;

//对list1容器排序
list1.sort();
    put_list(list1,"list1");

//结合处理
list1.splice(++list1.begin(), list3);
    put_list(list1,"list1");
    put_list(list3,"list3"); 
}
  • 7
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值