前言
STL是C++中非常重要的库,在找工作的时候,面试官就喜欢问这方面的问题。STL就是借助模板来实现各种数据结构。一、什么是STL/你用过STL吗?
STL 是“Standard Template Library”的缩写,中文译为“标准模板库”。STL 是 C++ 标准库的一部分,不用单独安装。
C++ 对模板(Template)支持得很好,STL 就是借助模板把常用的数据结构及其算法都实现了一遍,并且做到了数据结构和算法的分离。例如,vector 的底层为顺序表(数组),list 的底层为双向链表,deque 的底层为循环队列,set 的底层为红黑树,hash_set 的底层为哈希表。
STL主要有六个部件:
分配器 容器 迭代器 算法 适配器 仿函数
他们的关系如下所示:
其中,较为常用的是容器、迭代器、算法。
容器: 序列容器、关联容器、无序容器
迭代器是连接算法和容器的桥梁,区间为前闭后开。
算法指的是:max、min、find等算法
二、容器
2.1 vector的底层具体实现
vector的底层:
vector的类有三个指针成员变量,为start、finish以及end_of_storge
start指向开始内存头部,end_of_storge指向内存尾部,finish指向存的数据尾部。
template<class T, class Alloc= alloc>
class vector {
public:
typedef T value_type;
typedef value_type* iterator;
typedef value_type& reference;
typedef size_t size_type;
protected:
iterator start;
iterator finish;
iterator end_of_storage;
public:
iterator begin() { return start; }
iterator end() { return finish; }
size_type size() const { return size_type(end() - begin()); }
size_type capacity() const { return size_type(end_of_storage - begin());}
bool empty() const { return begin() == end(); }
reference operator[](size_type n) { return *(begin() + n); }
reference front() { return *begin(); }
reference back() { return *(end() - 1); }
};
当内存不足时,将会抛弃原来的内存,重新开辟一个两倍长度的内存。
容器 vector 的迭代器 start 指向第一个元素,迭代器 finish 指向最后一个元素的下一个元素,这两个迭
代器对应 begin() 和 end() 的返回值,维持了前闭后开的特性.
vector 对使用者是连续的,因此重载了 [] 运算符.
vector 的实现也是连续的,因此使用指针类型做迭代器(即迭代器 vector::iterator 的实际类型是 原生指针 T* ).
template<class T, class Alloc>
void vector<T, Alloc>::insert_ux(iterator position, const T &x)
{
if (finish != end_of_storage)
{ // 尚有备用空间,则将插入点后元素后移一位并插入元素
construct(finish, *(finish - 1)); // 以vector最后一个元素值为新节点的初值
++finish;
T x_copy = x;
copy_backward(position, finish - 2, finish - 1);
*position = x_copy;
} else
{
// 已无备用空间,则先扩容,再插入
const size_type old_size = size();
const size_type len = old_size != 0 ?: 2 * old_size:1; // 扩容后长度
为原长度的两倍
iterator new_start = data_allocator::allocate(len);
iterator new_finish = new_start;
try {
new_finish = uninitialized_copy(start, position, new_start);
// 拷贝插入点前的元素
construct(new_finish, x);
// 插入新元素并调整水位
++new_finish;
new_finish = uninitialized_copy(position, finish, new_finish);
// 拷贝插入点后的元素
}
catch (...)
{
// 插入失败则回滚,释放内存并抛出错误
destroy(new_start, new_finish) :
data_allocator::deallocate(new_start, len);
throw;
}
// 释放原容器所占内存
destroy(begin(), end());
deallocate();
// 调整迭代器
start = new_start;
finish = new_finish;
end_of_storage = new_start + len;
}
};
2.2 List的底层具体实现
将数组封装成容器 array 是为了使之与STL算法兼容,其内部实现只是简单封装了一下数组,甚至没有构造函数和析构函数.与 vector 一样使用原生指针做迭代器。
template<typename _Tp, std::size_t _Nm>
struct array {
typedef _Tp value_type;
typedef _Tp *pointer;
typedef value_type *iterator;
value_type _M_instance[_Nm ? _Nm : 1]; // Support for zero-sized arrays mandatory
iterator begin()
{
return iterator(&_M_instance[0]);
}
iterator end() {
return iterator(&_M_instance[_Nm]);
}
};
2.3 Deque的底层具体实现
2.4 array的底层具体实现
总结
提示:这里对文章进行总结:
例如:以上就是今天要讲的内容,本文仅仅简单介绍了pandas的使用,而pandas提供了大量能使我们快速便捷地处理数据的函数和方法。