STL

本文详细介绍了C++的STL,包括模板、函数模板、类模板及其特化,以及STL的主要组件:容器、迭代器、函数对象和通用算法。特别讨论了vector、list和deque这三种线性容器的特点和操作,如插入、删除、查找和排序。同时,提到了关联容器如map和set的使用,并强调了在多线程环境下原子数据类型和线程同步机制的重要性。
摘要由CSDN通过智能技术生成

STL

standard template library      标准模板库
template: 模板
将类型抽象化 将类型和算法分离 编写更加彻底抽象的算法 \函数\类

1.函数模板
语法规则:
template<typename T,…>
函数

函数模板  给类型之后实例化  模板函数  才生成对应类型的那个函数

对于某些特殊类型的,函数模板不一定适用,所以需要函数模板特化 (特殊处理)
函数模板全特化

2.类模板

template<typename T,…>
class 类{

};

类模板 --> 实例化  -->  模板类

(1)类模板全特化
全特化 意味着 整个类所有的成员 和 方法都需要重新写一遍,即使一些成员和方法一模一样
template<>
class 类名<特化的类型>{

};
(2)类模板成员特化
只针对某些成员方法进行特化处理 对于不需要进行特化理的不需要重新写过
template<>
返回值类型 class_name<特化的类型>::mem_name(形参列表){

}
(3)类模板的偏特化 函数模板不支持偏特化
针对类型参数相同 或者 针对 类型的指针 和 数组 进行局部特化
在实例化模板时,需要避免产生歧义

数据结构与算法 用模板实现是最好的

模板的类型可以有默认类型
模板可以有非类型参数
template

模板的非类型参数在实例化必须是常量表达式

在模板定义中 typename和class 可以互换

C++提供了很多类模板 函数模板 STL

STL:
容器、迭代器、函数对象、通用算法
十大容器:
1.线性容器
	vector:  向量 
	list: 列表
	deque: 双端队列
2.容器适配器
	queue: 队列 
	stack: 堆栈
	properity_queue: 优先队列
3.关联容器
	map:  映射
	multi_map: 多重映射
	set:  集合
	multi_set: 多重集合
*所有容器的共同特点:
1.支持自动扩容 
2.支持深拷贝  拷贝复制 和 拷贝赋值
3.支持 == 和 != 
	如果认为两个容器相等,则容器容量相等,且相同位置的元素也相等
4.往容器中存储元素时,是存储元素的副本(拷贝构造)
5.容器如果要支持sort 自定义类型需要重载< 或者提供比较的函数对象
	如果要支持find或者remove 则需要支持==比较
vector: 向量
特点:
1.内存连续
2.支持随机访问   []
3.在末尾增加元素效率高  
4.支持自动扩容 
方法:
1.构造函数
 vector();         //容量为0 元素为0
 vector( size_type num, const TYPE &val );//容量为num,元素个数num, 所有的元    素都是val
 vector( const vector &from );//拷贝构造
 vector( input_iterator start, input_iterator end );//[start,end) 区间的元素来构造
2.向量容量及元素个数
size()    向量在元素的个数
capacity() 向量在没有扩容之前容量的大小
empty()   向量是否为空
3.改变向量容量 和 元素个数
reserve()   设置Vector最小的元素容纳数量  一般只能扩大,不能变小
			只增加内存 不增加元素个数
resize()    设置vecotr中元素的个数  可增多  可减少   (类类型成员增加时调用无参构造和拷贝构造 减少调用析构)
			改变元素的个数 也可以间接改变 容量大小
			可以对新增加的元素指定  默认为"零" 或者调用无参构造
clear()     清空元素  容量不变
4.支持==和!=
两个vectors被认为是相等的,如果: 		
	1.它们具有相同的容量 
	2.所有相同位置的元素相等. 
5.assign 对向量元素赋值 清除赋值之前的元素
6.[]和at front back 返回引用
支持下标访问
[] 可能会越界访问  并不一定会报错   把越界访问的问题隐藏了
at 如果越界 直接抛出异常     可以用try-catch捕获

front()  back()   如果没有则出错
7.增加元素
push_back() 
在末尾增加一个元素
8.删除元素
pop_back() 
删除末尾的元素
9.插入元素
iterator insert( iterator loc, const TYPE &val );
void insert( iterator loc, size_type num, const TYPE &val );
void insert( iterator loc, input_iterator start, input_iterator end );
10.迭代器
正向迭代器:begin() end()   
	begin() 返回的是指向第一个元素的迭代器(指针)
	end()   返回最后一个元素的下一个迭代器(指针)
反向迭代器:rbegin() rend() 
11.erase 删除
根据迭代器删除
iterator erase( iterator pos );
iterator erase( iterator start, iterator end );
返回最后删除元素的下一个元素迭代器

swap 交换

12.遍历
for(int i=0;i<v.size();i++){
		v[i]
		v.at(i)
	}

	for(int& i:v){
		
	}

	for(vecotr<int>::iterator it=v.begin();it!=v.end();++it){
		*it
	}
13.查找
全局函数 find
template<typename IT,typename T>
IT find(IT begin,IT end,T key){
	for(IT it=begin;it!=end;it++){
		if(*it == key){
			return it;
		}
	}
	return end;
}
14.排序
全局函数 sort
template<typename IT>
void sort(IT begin,IT end){
	for(IT it = begin; it != end;it++){
		for()
	}
}
template<typename IT,typename CT>
void sort(IT begin,IT end,CT comp){
	
}
list: 列表

全局的sort函数不支持list 因为list的内存不连续 list的迭代器不支持减法运算

特点:
1.内存不连续
2.访问时间复杂度 O(n)
3.在任何位置插入和删除效率都比较高

比vector多了 push_front() pop_front() back() front()

(1)merge  合并两个列表    把另外一个列表的元素比较插入到当前列表
	如果两个列表有序  merge 有序
(2)erase  删除迭代器指定的元素    返回删除最后一个元素的下一个元素的迭代器	

vector<int> v(10,10);
vecotr<int>::iteartor it = v.begin();
for(;it!=v.end();it++){//两个连续的10 ,只能删除一个
	if(*it == 10){
		v.erase(it);
	}
}
list<int> l(10,10);
list<int>::iterator it = l.begin();
for(;it!=l.end();it++){//核心段错误
	if(*it == 10){
		l.erase(it);  
	}
}
(3)	remove 删除值相等的对象  ==   对象需要重载==运算符
    remove_if  按指定条件删除
	class Com{
	private:
		int no;	
	public:
		Com(int no):no(no){}
		bool operator()(const Emp& e){
			//返回true删除  
			return e.no == no;
		}
	};
	Com(10) 
(4) reverse  逆序
(5) sort  排序
	list不可以用全局的sort函数
(6) splice   把另外一个列表或者迭代器区间的元素合并到当前list
(7) unique   删除连续重复元素只保留一个   不连续的并不判断
	按指定条件删除
	class Com{
	public:
		bool operator()(const T& pre,const T& curr){
			//pre是前一对象   curr是当前对象   如果返回true 则把curr对象从列表中删除
		}
	};
(8) list不支持随机迭代 
	正向迭代器  和 反向迭代器    支持 ++ --  *   不支持+ 和 -
3.deque 双端队列
和vector相似  但它允许在容器开头位置进行快速的插入和删除
比vector多了push_front() 和 pop_front()

容器适配器:

对list,vector和deque进行了封装,只提供了某些接口(函数)

容器适配器: 都可以指定底层的实现 所谓适配 就是提供满足数据结构的接口

4.stack 堆栈 先进后出
empty()
push()
pop()
size()
top()
stack<元素的类型,底层实现的类型>
5.queue 队列
底层实现不能是vector
在两端进行操作   
empty()
push()    调用底层实现的push_back()
pop()     调用底层实现的pop_front()     因为vector没有pop_front 所以vector不能作为queue的底层
front()
back()
size()
6.priority_queue 没有自己的头文件 和 queue共用头文件
优先队列在push元素时,相当于插入排序一样  插入到指定位置
对数据进行排序  排在最后面的优先级更高(优先出队列)
底层实现不能是list
priority_queue<元素类型,底层实现类型,优先指定类型>
	优先指定类型  默认是要怕元素类型的 < 
	底层实现类型  默认是deque

把学生对象放到优先队列中  要求每次取出来的都是学习成绩最好的那个学生 如果成绩一样,取学号较小
关联容器:
底层是红黑树
7.map 映射
查找效率高
map 存储的是 (KVP  key-value pairs) 键值对
	类似于python中的字典
	key唯一
	根据key来构建红黑树
pair<key_type,value_type> p;
构造pair对象:
	直接调用构造函数:  pair<key_type,value_type> p(key,value);
	调用函数返回一个:  make_pair<key_type,value_type>(key,value);
	pair对象如何访问key和value
		pair里面有两个成员: first   second
map<key_type,value_type,comp_type>
(1)insert 把pair对象插入到map中,如果key重复 则插入失败
	返回 pair<iterator,bool> 类型对象  
		iterator迭代器指向插入的这个元素  bool 表示插入是否成功
   mapobj[key] = value;   如果key不存在则往映射中插入key-value pair  
                          如果key存在则更新value的值
(2)find  根据key查找   不是根据value
	find在比较时不是调用==进行比较
	而是调用<进行比较    它怎么确定是要找的那个key呢?     
			node->key < key || key < node->key == false 表示  node->key == key;
8.multimap 多重映射
key值可以重复
因为multimap中可以存在多个key相同的记录,所以不能用 []
pair equal_range(const key_type &key )
	返回一个记录 值等于key的区间
	pair第一个迭代器为第一个键==key的记录   第二个迭代器为最后一条键==key的下一条记录
9.set集合
只有key没有value
key唯一
自定义类型存储到set中需要重载<运算符
find()  根据 <  进行比较
可以指定比较规则
set<元素类型,比较规则类型>   比较规则没有时默认按照元素类型的<
10.multiset 多重集合
元素可以重复

在map容器中的key 还是 set窗口中的元素  都不允许修改
	因为在一棵有序二叉树中 不允许对节点的元素进行修改
11.bitset
二进制位集合
12.string
find
没有找到返回 string::npos
auto 万能类型
auto ret = func();
nullptr
比NULL更能代表空指针
for循环
for(auto& val:数组/容器变量){}
容器支持迭代器
array 数组
forward_list 单向链表
list: 双向链表
unordered_map
map,multimap,set,multiset  底层是红黑树实现   查找效率O(logn)
unordered_map,unordered_set  底层用哈希表实现   O(1)
	哈希表最大的缺点:
		rehash  哈希表在不断地插入和删除之后可以需要重新哈希
		内存增长

如果数据固定:
	一定是用哈希结构来存储这些数据  能够保证最快的查找效率
多线程
#include <thread>
原子数据类型
#include <atomic>
atomic_int    原子数据类型  操作原子数据类型变量时 相当于底层自动上锁
线程互斥锁
#include <mutex>
条件变量
#include <condition_variable>

用上述内容实现生产者消费者模型
智能指针
auto_ptr
shared_ptr
weak_ptr
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值