C++——STL标准模板库(算法、容器、迭代器)

在被引入C++之前该技术就已经存在了很长的一段时间。后来STL成为ANSI/ISO C++标准的一部分。各个C++厂商也有各自相应的模板库,这些库效率可能很高,但可移植性不一定好。

STL以迭代器(Iterators)和容器(Containers)为基础,是一种泛型算法(Generic Algorithms)库,容器的存在使这些算法有东西可以操作。迭代器(Iterators)是STL的核心,它们是泛型指针,是一种指向其他对象(objects)的对象,迭代器能够遍历由对象所形成的区间(range)。

STL广义上分为三类:algorithm(算法)、container(容器) 和 iterator(迭代器),几乎所有的代码都采用了模板类和模板函数的方式,这相比于传统的由函数和类组成的库来说提供了更好的代码重用机会。

在C++标准中,STL被组织为下面的13个头文件:

2 算法(algorithm)

STL提供了大约100个实现算法的模版函数,算法部分主要由头文件, 和组成。

是所有STL头文件中最大的一个,它是由一大堆模板函数组成的,其中常用到的功能范围涉及到比较、

交换、查找、遍历操作、复制、修改、移除、反转、排序、合并等等。

体积很小,只包括一些简单数学运算的模板函数。

中则定义了一些模板类,用以声明函数对象。

3.容器(container)(又称集合collection)

1)容器用来存储数据的集合,数据可以是用户自定义类型,也可以是预定义类型。

2)容器类自动申请和释放内存,无需new和delete操作。所有容器类的使用都需要引入对应的头文件,因为这些类型都是std名字空间下的类。

3)C++中有两种类型的容器:顺序容器和关联容器

C++——STL标准模板库(算法、容器、迭代器)_第1张图片

①顺序容器:

是一种各元素之间有顺序关系的线性表,是一种线性结构的可序群集。

顺序性容器中的每个元素均有固定的位置,除非用删除或者插入的操作改变这个位置。

(一)array

  • 长度固定!
  • 长度只能是常数,不能传变量。
#include 
#include  // 头文件

using namespace std;

int main()
{
    // 创建一个长度为5的int数组
    array arr = {1,2,3};
    // 修改数据
    arr[0] = 111;
    arr.at(1) = 222;

    // 遍历输出
    for(int i:arr)
        cout << i << endl;

    // 给所有元素赋一个统一的值
    arr.fill(-1);

    // for循环
    for(int i = 0;i

(二)vector

  • 长度不固定,可以变化!
  • 底层是数组,也可以实现随机存取
#include 
#include  // 头文件
using namespace std;
int main()
{
    // 创建一个长度为5的向量
    vector vec(5);
    cout << vec.size() << endl; // 5

    // 修改元素
    vec[0] = 111;
    vec.at(1) = 222;

    // 在第一个位置插入数据101
    // vec.begin()可以返回一个迭代器指针,指向第一个元素
    vec.insert(vec.begin(),101);
    // 在第三个位置插入数据333
    vec.insert(vec.begin()+2,333);
    // 在最后的位置插入数据-1
    vec.push_back(-1);
    // 新插入的数据是倒数第三个,插入数据为-333
    // vec.end()可以返回一个迭代器指针,指向最后一个元素的后面
    vec.insert(vec.end()-2,-333);

    // 删除最后一个数据
    vec.pop_back();
    // 删除第四个数据
    vec.erase(vec.begin()+3);
    // 删除倒数第四个数据
    vec.erase(vec.end()-4);

    // 遍历
    for(int i:vec)
        cout << i << " ";
    cout << endl;

    vec.clear(); // 清空
    cout << vec.empty() << endl; // 1

    for(int i=0;i

(三)list

  • 底层逻辑是双向链表
  • 更善于增加和删除,遍历的效率慢
  • 迭代器指针的移动:iter++/advance(iter,10);
#include 
#include  // 头文件

using namespace std;
int main()
{
    // 创建一个长度为5的列表
    list lis(5);

    cout << lis.size() << endl;

    // iterator是一种特殊的指针,高度封装
    list::iterator iter = lis.begin();
    // 修改元素
    *iter = 111; // 把第一个元素改为111
    iter++; // 移动到第二个位置
    *iter = 222;

    // 在第一个位置插入101
    lis.push_front(101);
    iter = lis.begin();
    advance(iter,2); // 向后移动2个位置
    // 在第三个位置插入333
    lis.insert(iter,333);
    // 在最后的位置插入-1
    lis.push_back(-1);
    iter = lis.end();
    advance(iter,-2); // 向前移动2个位置
    // 新插入的数据是倒数第三个,插入数据为-333
    lis.insert(iter,-333);
    // 删除最后一个数据
    lis.pop_back();
    // 删除第一个数据
    lis.pop_front();
    // 删除第四个数据
    iter = lis.begin();
    advance(iter,3);
    lis.erase(iter);
    // 删除倒数第四个数据
    iter = lis.end();
    advance(iter,-4);
    lis.erase(iter);

    // 排序(前提是存储的数据支持排序)
    lis.sort();

    // 清空
    lis.clear();
    cout << lis.empty() << endl;

    // for-each
    for(int i:lis)
        cout << i << " ";
    cout << endl;

    return 0;
}

(四)deque

②关联容器:

主要讲解map:键值对映射

关联容器的元素没有严格的顺序关系,但是内部有排序,因此才可以被迭代器遍历

每个元素的数据被称为值(value),每个元素拥有一个独一无二的名称:键(key),所以一个完整的元素被称为键值对。

map的底层原理--数据结构(!红黑树!)

#include 
#include  // 头文件

using namespace std;


int main()
{
    // 创建一个map对象
    map map1;

    // 增加元素
    map1["身高"] = 177;
    map1.insert(pair("月薪",18000));
    // 如果已经有了键,则不修改值
    map1.insert(pair("月薪",18001));
    // 如果已经有了键,则修改值
    map1["身高"] = 180;

    // 取出元素
    cout << map1["月薪"] << endl;
    cout << map1.at("身高") << endl;
//    cout << map1.at("年龄") << endl; 没有数据则崩溃
    // 没有数据则创建 年龄:0
    cout << map1["年龄"] << endl;

    // 判断键值对是否存在
    map::iterator iter = map1.find("年龄");
    // 删除键值对
    if(iter == map1.end())
        cout << "无法删除,查无此键!" << endl;
    else
        map1.erase("年龄");

    map1.clear(); // 清空

    cout << map1.size() << endl;
    cout << map1.empty() << endl;

    return 0;
}

3.迭代器

各类容器迭代器的遍历方法:

#include 
#include 
#include 
#include 
#include 
#include 
#include  // 头文件

using namespace std;


int main()
{
    string str = "ABJFG";
    for(string::const_iterator iter = str.begin();iter != str.end();iter++)
        cout << *iter << " ";
    cout << endl;

    array arr = {"fdsf","fdf","sd","tr","xx"};
    for(array::const_iterator iter = arr.begin();iter != arr.end();iter++)
        cout << *iter << " ";
    cout << endl;

    vector vec(6,"哈哈哈");
    vector::const_iterator iter = vec.begin();
    while(iter != vec.end())
    {
        cout << *iter << " ";
        iter++;
    }
    cout << endl;

    list lis(6,"呵呵呵");
    for(list::iterator iter = lis.begin();iter != lis.end();iter++)
        cout << *iter << " ";
    cout << endl;

    deque deq(5);
    for(deque::iterator iter = deq.begin();iter != deq.end();iter++)
        cout << *iter << " ";
    cout << endl;

    map map1;
    for(map::iterator iter = map1.begin();iter!=map1.end();iter++)
    {
        cout << iter->first << " " << iter->second << endl;
    }

    return 0;
}

你可能感兴趣的:(c++,算法,java)