STL
什么是STL
STL(Standard Template Library)是C++标准库的一部分(80%),是用C++ Template机制来表达泛型的库。
面向过程——基于对象——面向对象——泛型
STL其实就是一个模板库,这个模板库主要由以下几个组件组成:
Iterator(迭代器):正向迭代器、反向迭代器、文件流迭代器。
Container(容器):数组、链表、栈、队列、set、map等。
Algorithm(算法):对容器进行查找、排序、遍历等操作。
Adaptors(适配器):适配器是标准库中通用的概念,包括容器适配器、迭代器适配器和函数适配器。
本质上,适配器是使一事物的行为类似于另一类事物的行为的一种机制。
容器适配器让一种已存在的容器类型采用另一种不同的抽象类型的工作方式实现。例如,stack适配器可使任何一种顺序容器以栈的方式工作。
http://blog.sina.com.cn/s/blog_9946f55601016qwk.html
迭代器
迭代器实际是也是一个指针。是经过封装的指针类。
迭代器对象名称就是迭代器的地址。
iterator._Ptr是迭代器对象指向数据的地址。当使用++、–、或*操作符时实际上就是对_Ptr进行操作。
迭代器主要有以下类型:
正向迭代器
反向迭代器
文件流迭代器
环境说明:windows7(64bit)、QT5.4.1
// 迭代器
#include<stdio.h>
void iteratorTest(){
vector<int> arr = {
1,2,3,4,5,6,7,8};
vector<int>::const_iterator ib = arr.begin();
vector<int>::const_iterator ie = arr.end();
//printf("%p %p \n\n", ib._Ptr, ib);
for(;ib != ie; ++ib){
//printf("%p %p \n", ib, ib._Ptr);
printf("%p %p \n", ib._Ptr, ib);
}
}
打印结果如下:
在64位系统地址是16位的,可以每次打印ib看到的都是同一个地址,但ib._Ptr在++ib后每次都有变化。
容器
array(静态数组)
//静态数组:可随机访问,内存分配在栈上,长度不可变
#include<array>
void main(){
// 定义一个大小为5的数组
std::array<int,5> arr = {
1,2,3,4,5};
arr[0] = 1;
arr[1] = 3;
arr[2] = 2;
cout<<"size="<<arr.size()<<endl;
// 打印每个元素
for_each(arr.begin(), arr.end(), [](int i){ //lambda表达式
cout<<i<<endl;
});
}
vector(动态数组)
// 动态数组:可随机访问,插入和删除效率较低,内存分配在堆上,长度可动态变化
#include<vector>
void vectorTest()
{
vector<int> arr = {
1,2,3,4,5};
// 添加元素
arr.push_back(6);
// 随机访问
arr[5] = 7;
//删除索引为0—1的元素
arr.erase(arr.begin(),arr.begin()+2);
// 迭代,打印
for_each(arr.begin(), arr.end(), [](int val){
cout<<val<<endl;
});
}
list(链表)
// 链表:插入和删除时间复杂度为O(1),相对效率较高,随机访问效率为O(n),相对效率较低。
#include<list>
void listTest(){
list<int> l;
//在结尾添加元素
l.push_back(1);
l.push_back(2);
//在开头添加元素
l.push_front(3);
list<int>::iterator ib = l.begin();
++ib;//链式结构容器的迭代器不能使用+操作符...只能这样了...
++ib;
// 第3个位置插入一个元素
l.insert(ib, 100);
// 迭代打印
for_each(l.begin(), l.end(), [](int val){
cout<<val<<endl;
});
}
注意:merge和unique函数依赖于sort,也就是合并list和去除重复元素这两个操作是在list有序的前提下才可执行。
stack(栈)
#include <stack>
// 栈(stack):先进后出,后进先出。
void main()
{
// 把一个数字转换为二进制
int a = 100;
stack<int> s;
// 一个数字不断除以2的余数,由下往上的数字序列就是其二进制数
while(a){
s.push(a%2);
a/=2;
}
// 打印该数字的二进制数
while(!s.empty()){
cout<< s.top();
s.pop();
}
cout<<endl;
}
queue(队列)
#include<queue>
//队列(queue):先进先出。
void main(){
queue<int> q;
// 入队
q.push(1);
q.push(1);
q.push(0);
q.push(1);
q.push(0);
// 打印队列元素个数
cout<<"queue size : "<<q.size()<<endl;
while(!q.empty()){
cout<<q.front();
// 出队
q.pop();
}
cout<<endl;
}