zoukankan      html  css  js  c++  java
  • 标准模板库STL介绍

    库是一系列程序组件的集合,他们可以在不同的程序中重复使用。C++语言按照传统的习惯,提供了由各种各样的函数组成的库,用于完成诸如输入/输出、数学计算等功能。

    1. STL介绍

    标准模板库STL是当今每个从事C++编程的人需要掌握的技术,所有很有必要总结下

    本文将介绍STL并探讨它的三个主要概念:容器、迭代器、算法。

    STL的最大特点就是:

    数据结构和算法的分离,非面向对象本质。访问对象是通过象指针一样的迭代器实现的;

    容器是象链表,矢量之类的数据结构,并按模板方式提供;

    算法是函数模板,用于操作容器中的数据。由于STL以模板为基础,所以能用于任何数据类型和结构。

    容器可以分为三种主要类型:序列容器、关联容器、容器适配器。

    每种STL容器都具有相关联的成员函数,这些成员函数的一个子集在所有的STL容器中都定义了。

    STL迭代器的属性和指针类似,程序可以利用迭代器操作STL容器中的元素

    STL算法是用于执行常见数据操作的函数,这些操作包括搜索、排序和比较元素,STL提供了大约70种算法,其中大多数算法都使用迭代器来访问容器元素。

    1.1   容器简介

     容器可以分为三种:序列容器、关联容器、容器适配器。

    序列容器:vector deque list

    Vector:可从后端执行快速的插入和删除,直接访问任何元素

    Deque:从前面或后面执行快速的插入和删除,直接访问任何元素

    List:双链表,能在任何地方执行快速的插入和删除

    关联容器:set multiset map multimap

    Set:执行快速搜索,元素不允许重复

    Multiset:执行快速搜索,元素允许重复

    Map:一对一映射,元素不允许重复,快速的基于键的搜索

    Multimap:一对多映射,元素允许重复,快速的基于键的搜索

    容器适配器:stack queue priority_queue

    Stack:后进先出

    Queue:先进先出

    priority_queue:优先级最高的元素总是最先出队

    序列容器表示线性数据结构,例如向量和链表;

    关联容器是非线性容器,通常能够快速找出保存在容器中的元素。这类容器能够保存值的集合或键/值对;序列容器和关联容器统称为第一类容器。

    STL将堆栈和队列实现为容器适配器,使程序以一种受约束的方式看待序列容器。

    STL通常可通过模板实现泛型编程,以避免继承和虚函数,获得更好的执行时性能。

    1.2   迭代器简介

    迭代器在许多方面和指针相同,用于指向第一类容器的元素。

    迭代器提供对一个容器中的对象的访问方法,并且定义了容器中对象的范围。迭代器就如同一个指针。事实上,C++的指针也是一种迭代器。但是,迭代器不仅仅是指针,因此你不能认为他们一定具有地址值。例如,一个数组索引,也可以认为是一种迭代器。

    迭代器有各种不同的创建方法。程序可能把迭代器作为一个变量创建。一个STL容器类可能为了使用一个特定类型的数据而创建一个迭代器。作为指针,必须能够使用*操作符类获取数据。你还可以使用其他数学操作符如++。典型的,++操作符用来递增迭代器,以访问容器中的下一个对象。如果迭代器到达了容器中的最后一个元素的后面,则迭代器变成past-the-end值。使用一个past-the-end值得指针来访问对象是非法的,就好像使用NULL或为初始化的指针一样。

     

     

     

     

     

     

     

     

     

     

     

    容器适配器

    首先,我们要明白适配器是干什么的?其实就是一个接口转换装置,是得我们能用特定的方法去操作一些我们本来无法操作的东西。举一个例子,比如你的一个设备支持串口线,而你的电脑支持的是usb口,这时候,我们没有必要重新买一个支持usb的设备,只需要一根串口转usb口的小玩意,让你的设备能够连接到usb插口上,而它就是适配器。
    那么C++中的容器适配器是干什么的呢?可以做一个类比,我们已有的容器(比如vector、list、deque)就是设备,这个设备支持的操作很多,比如插入,删除,迭代器访问等等。而我们希望这个容器表现出来的是栈的样子:先进后出,入栈出栈等等,此时,我们没有必要重新动手写一个新的数据结构,而是把原来的容器重新封装一下,改变它的接口,就能把它当做栈使用了。
    言归正传,理解了什么是适配器以后,其实问题就很简单的。C++中定义了3种容器适配器,它们让容器提供的接口变成了我们常用的的3种数据结构:栈(先进后出)队列(先进先出)和优先级队列(按照优先级(“<”号)排序,而不是按照到来的顺序排序)。
    至于具体是怎么变的,我们可以先了解一个大概:默认情况下,栈和队列都是基于deque实现的,而优先级队列则是基于vector实现的。当然,我们也可以指定自己的实现方式。但是由于数据结构的关系,我们也不能胡乱指定。

    栈的特点是后进先出,所以它关联的基本容器可以是任意一种顺序容器,因为这些容器类型结构都可以提供栈的操作有求,它们都提供了push_back、pop_back和back操作。

    队列queue的特点是先进先出,适配器要求其关联的基础容器必须提供pop_front操作,因此其不能建立在vector容器上;对于优先级队列,由于它要求支持随机访问的功能,所以可以建立在vector或者deque上,不能建立在list上。

    让我们看看这三种关联容器提供的接口:
    栈支持的操作有:
    1.empty()  堆栈为空则返回真
    2.pop()  移除栈顶元素
    3.push()  在栈顶增加元素
    4.size()  返回栈中元素数目
    5.top()  返回栈顶元素
    队列支持的操作有:
    1.back()  返回一个引用,指向最后一个元素
    2.empty()  如果队列空则返回真
    3.front()  返回第一个元素
    4.pop()  删除第一个元素
    5.push()  在末尾加入一个元素
    6.size()  返回队列中元素的个数
    优先级队列支持的操作有:
    1.empty()  如果优先队列为空,则返回真
    2.pop()  删除第一个元素
    3.push()  加入一个元素
    4.size()  返回优先队列中拥有的元素的个数
    5.top()  返回优先队列中有最高优先级的元素

     

     

     

     

     

    ///*
    #include<iostream>
    #include<string>
    #include<stack>
    using namespace std;
    int main()
    {
     stack<string>test;
    test.push("back");
    test.push("middle");
    test.push("front");


    cout<<test.top()<<endl;
    test.pop();

    cout<<test.top()<<endl;
    return 0;
    }

    //*/
    /*
    #include<iostream>
    #include<string>
    #include<queue>
    using namespace std;
    int main()
    {
     queue<string>test;
    test.push("back");
    test.push("middle");
    test.push("front");


    cout<<test.front()<<endl;
    test.pop();

    cout<<test.front()<<endl;
    return 0;
    }

    */

     

     

     

  • 相关阅读:
    BFS visit tree
    Kth Largest Element in an Array 解答
    Merge k Sorted Lists 解答
    Median of Two Sorted Arrays 解答
    Maximal Square 解答
    Best Time to Buy and Sell Stock III 解答
    Best Time to Buy and Sell Stock II 解答
    Best Time to Buy and Sell Stock 解答
    Triangle 解答
    Unique Binary Search Trees II 解答
  • 原文地址:https://www.cnblogs.com/lengxia/p/4387808.html
Copyright © 2011-2022 走看看