C++_STL总结

1、STL

STL是标准模板库:是高效的C++程序库,其采用泛型编程思想对常见数据结构(顺序表、链表、栈和队列、堆、二叉树、哈希)和算法(查找、排序、集合、数值运算)等进行封装,体现着泛型编程程序设计思想以及设计模式,已被集成到C++标准程序库中。

STL中包含了容器、适配器、算法、迭代器、仿函数以及空间配置器。

STL设计理念:追求代码高复用性以及运行速度的高效率。

2、STL六大组件

容器

分为序列式容器和关联式容器。

容器适配器:

  • stack:底层是对deque的重新封装
  • queue:底层是对deque的重新封装
  • priority_queue:底层是对vector的重新封装,大根堆

序列式容器:

  • array:静态顺序表
  • string:字符串
  • vector:动态顺序表
  • forward_list:带头节点的循环单链表
  • list:带头节点的双向循环链表
  • deque:动态二维数组

关联式容器:

  • map:红黑树结构,key唯一键值对
  • multimap:红黑树结构,key可重复键值对
  • set:红黑树结构,value唯一
  • multiset:红黑树结构,value可重复
  • unordered_map:哈希结构,key唯一键值对
  • unordered_multimap:哈希结构,key可重复键值对
  • unordered_set:哈希结构,value唯一
  • unordered_multiset:哈希结构,value可重复

算法

算法:问题的求解步骤,以有限的步骤解决数学或逻辑中的问题。

STL中的算法主要分为两大类:与数据结构相关算法(容器中的成员函数)和通用算法(与数据结构不相干)。

STL中通用算法主要包含:排序、查找、排列组合、数据移动、拷贝、删除、比较组合、运算等。STL常用算法

如find算法,find算法在查找时,与具体的数据结构无关,只要给出待查找数据集合的范围,find就可在该范围中查找,找到返回该元素在区间中的位置,否则返回end。

template<class InputIterator, class T>
InputIterator find(InputIterator first, InputIterator last, const T& value)
{
	while(first != last)
	{
		if(*first == value)
			break;
		first++;
	}
	return first;
}

迭代器

迭代器是一种设计模式,让用户通过特定的接口访问容器的数据,不需要了解容器内部的底层数据结构。C++中迭代器本质是一个指针,让该指针按照具体的结构去操作容器中的数据。

每个容器的底层结构都不同,为了降低算法使用容器时的复杂度,底层结构应该对于算法透明,迭代器就充当了算法与容器之间的转接层,因此每个容器的迭代器应该由容器设计者负责提供,然后容器按照约定给出统一的接口即可。

实现原理:

容器底层结构不同,导致其实现原理不同,容器迭代器的设计,必须结合具体容器的底层数据结构。比如vector与list,因为vector底层结构为一段连续空间,迭代器前后移动时比较容易实现,因此vector的迭代器实际是对原生态指针的封装:typedef T* iterator;。list底层结构为带头结点的双向循环链表,迭代器在移动时只能按照链表的结构前后依次移动,因此链表的迭代器需要对原生态的指针进行封装,因为当对迭代器++时,应该通过节点中的next指针域找到下一个节点:typedef list_iterator<T, T&, T*> iterator;

如果迭代器不能直接使用原生态指针操作底层数据时,必须要对指针进行封装,在封装时需要提供以下方法:

  • 迭代器能够像指针一样方式进行使用:重载pointer operator*() / reference operator->()
  • 能够让迭代器移动:向后移动重载self& operator++() / self operator++(int);向前移动重载self& operator--() / self operator--(int)
  • 支持比较(因为在遍历时需要知道是否移动到区间的末尾):bool operator!=(const self& it) const / bool operator==(const self& it) const

迭代器类的实现:

  1. 定义迭代器类(如list)
  2. 在容器类中统一迭代器名字
template<class T, class Alloc = alloc>
class list
{
	typedef __list_iterator<T, T&, T*> iterator;
};
  1. 在容器类中添加获取迭代器范围的接口
template<class T, class Alloc = alloc>
class list
{
	typedef __list_iterator<T, T&, T*> iterator;
	iterator begin()
	{
		return (link_type)((*node).next);
	}
	iterator end()
	{
		return node;
	}
};

适配器

适配器:将一个类的接口转换成用户希望的另一个类的接口,使原本接口不兼容的类可以一起工作。STL适配器有三种:

  • 容器适配器:stack、queue
  • 迭代器适配器:反向迭代器。反向迭代器++和–操作刚好和正向迭代器相反,因此反向迭代器只需将正向迭代器进行重新封装即可。
  • 函数适配器

仿函数

仿函数:一种具有函数特征的对象,调用者可以像函数一样使用该对象,为了能够“行为类似函数”,该对象所在类必须自定义函数调用运算符operator(),重载该运算符后,就可在仿函数对象的后面加上一对小括号,以此调用仿函数所定义的operator()操作。就其行为而言,“仿函数”一次更切贴。仿函数一般配合算法,提高算法的灵活性。

#include<iostream>
#include<vector>
#include<algorithm>

using namespace std;

class _mul_two
{
public:
	void operator()(int& data)
	{
		data <<= 1;
	}
};

class _mod_three
{
public:
	bool operator()(int data)
	{
		return data % 3 == 0;
	}
};

int main()
{
	vector<int> vec{1, 2, 3, 4, 5, 6, 7, 8, 9, 0};
	for_each(vec.begin(), vec.end(), _mul_two());
	for(auto e : vec)
	{
		cout<<e<<" ";
	}
	cout<<endl;
	auto pos = remove_if(vec.begin(), vec.end(), _mod_three());
	vec.erase(pos, vec.end());
	for_each(vec.begin(), vec.end(), [](int data){cout<<data<<" ";});
	cout<<endl;
	return 0;
}

空间配置器

空间配置器:顾名思义就是为各个容器高效的管理空间(空间的申请与回收)的,在默默地工作。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值