c++ (P262—P277) STL

STL的六大组件

  • 容器(Container),是一种数据结构,如list,vector,和deques ,以模板类的方法提供。为了访问容器中的数据,可以使用由容器类输出的迭代器;
  • 迭代器(Iterator),提供了访问容器中对象的方法。例如,可以使用一对迭代器指定list或vector中的一定范围的对象。迭代器就如同一个指针。事实上,C++的指针也是一种迭代器。但是,迭代器也可以是那些定义了operator*()以及其他类似于指针的操作符地方法的类对象;
  • 算法(Algorithm),是用来操作容器中的数据的模板函数。例如,STL用sort()来对一个vector中的数据进行排序,用find()来搜索一个list中的对象,函数本身与他们操作的数据的结构和类型无关,因此他们可以在从简单数组到高度复杂容器的任何数据结构上使用;
  • 仿函数(Function object,仿函数(functor)又称之为函数对象(function object),其实就是重载了()操作符的struct,没有什么特别的地方
  • 迭代适配器(Adaptor)
  • 空间配制器(allocator)其中主要工作包括两部分1.对象的创建与销毁    2.内存的获取与释放

1 容器  

  1)序列式容器(Sequence containers),每个元素都有固定位置--取决于插入时机和地点,和元素值无关,vector、deque、list;

   Vectors:将元素置于一个动态数组中加以管理,可以随机存取元素(用索引直接存取),数组尾部添加或移除元素非常快速。但是在中部或头部安插元素比较费时;

  

主要函数有:
    vector<T>::iterator  begin(); 返回向量首地址
    vector<T>::iterator  end();   返回末尾地址加 1 
    void push_back();向end()位置添加一位,end()指针自动加 1
    void pop_back();将end()-1位置元素弹出
    void clear(); 清空向量
    bool empty(); 判断向量是否为空,如果是空则返回1
    void insert(iterator it ,const_iterator first ,const_iterator last); 
    void insert(iterator it ,const_iterator first ,const_iterator last);
  
  

    #include <iostream>
    #include <string>
    #include <stack>
    #include <vector>
    using namespace std;


    int main()
    {
    int i;
    vector<int> vec,vecc;
    vector<int>::iterator vbegin,vend;
    vector<int>::iterator vbeginc,vendc;

    for(int i=0;i<2;i++)
    vec.push_back(i);
    vbegin=vec.begin();
    vend=vec.end();

    vecc.push_back(100);
    vecc.push_back(1000);
    vecc.push_back(10000);
    vbeginc=vecc.begin();

    vecc.insert(vbeginc,vbegin,vend);

    vecc.pop_back();

    vbeginc=vecc.begin();
    vendc=vecc.end();
    while(vbeginc!=vendc)
    {
    cout<<*vbeginc<<endl;
    vbeginc++;
    }

    return 0;
    }

  打印结果为:

  0

   1

  100

  1000

  使用这些函数时注意点end()返回的地址只能用于判断不能用于寻址,insert插入函数也要从begin处插入,插入后重新获  取向量的首末地址。

 

   Deques:是“double-ended queue”的缩写,可以随机存取元素(用索引直接存取),数组头部和尾部添加或移除元素都非常快速。但是在中部或头部安插元素比较费时;

   Lists:双向链表,不提供随机存取(按顺序走到需存取的元素,O(n)),在任何位置上执行插入或删除动作都非常迅速,内部只需调整一下指针;

  2)关联式容器(Associated containers),元素位置取决于特定的排序准则,和插入顺序无关,set、multiset、map、multimap;

   Sets/Multisets:内部的元素依据其值自动排序,Set内的相同数值的元素只能出现一次,Multisets内可包含多个数值相同的元素,内部由二叉树实现(实际上基于红黑树(RB-tree)实现),便于查找;

   Maps/Multimaps:Map的元素是成对的键值/实值,内部的元素依据其值自动排序,Map内的相同数值的元素只能出现一次,Multimaps内可包含多个数值相同的元素,内部由二叉树实现(实际上基于红黑树(RB-tree)实现),便于查找;

另外有其他容器hash_map,hash_set,hash_multiset,hash_multimap。

2.STL迭代器 

Iterator(迭代器)模式又称Cursor(游标)模式,用于提供一种方法顺序访问一个聚合对象中各个元素, 
而又不需暴露该对象的内部表示。或者这样说可能更容易理解:Iterator模式是运用于聚合对象的一种模式,通过运用该模式,使得我们可以在不知道对象内部表示的情况下,按照一定顺序(由iterator提供的方法)访问聚合对象中的各个元素。

迭代器的作用:能够让迭代器与算法不干扰的相互发展,最后又能无间隙的粘合起来,重载了*,++,==,!=,=运算符。用以操作复杂的数据结构,容器提供迭代器,算法使用迭代器;

常见的一些迭代器类型:iterator、const_iterator、reverse_iterator和const_reverse_iterator

迭代器一般声明使用示例

vector<T>::iterator it;
list<T>::iterator it;
deque<T>::iterator it;

  

4.适配器

STL提供了三个容器适配器:queue、priority_queue、stack。这些适配器都是包装了vector、list、deque中某个顺序容器的包装器。注意:适配器没有提供迭代器,也不能同时插入或删除多个元素。下面对各个适配器进行概括总结。


(1)stack用法

#include <stack>
template < typename T, typename Container=deque > class stack;

可以使用三个标准顺序容器vecotr、deque(默认)、list中的任何一个作为stack的底层模型。

(2)queue用法

#include <queue>
template<typename T, typename Container = deque<T> > class  queue;

第一个参数指定要在queue中存储的类型,第二个参数规定queue适配的底层容器,可供选择的容器只有dequeue和list。对大多数用途使用默认的dequeue。

对于stack:
    void push(const T& x);将对象x压入栈中
    void pop;将栈顶元素弹出栈
    int size() const; 获取栈中元素个数
    const value_type& top() const; 查询栈顶元素
    bool empty() const; 判断栈是否为空
 

对于queue:
    
    void push(const T& x);从尾进队
    void pop();从头出队
    const value_type& front();查询对首
    const value_type& back();查询对尾
    int size() const;获取个数
    bool empty() const;判读是否为空

 

(3)priority_queue用法

#include <queue>
template <typename T, typename Container = vector<T>, typename Compare = less<T> > class priority_queue;

priority_queue也是一个队列,其元素按有序顺序排列。其不采用严格的FIFO顺序,给定时刻位于队头的元素正是有最高优先级的元素。如果两个元素有相同的优先级,那么它们在队列中的顺序就遵循FIFO语义。默认适配的底层容器是vector,也可以使用deque,list不能用,因为priority_queue要求能对元素随机访问以便进行排序。

priority_queue<T>::push(T x)
void priority_queue<T>::pop()
T priority_queue<T>::top()
priority_queue<T>::size_type 
priority_queue<T>::size()
bool priority_queue<T>::empty()

代码示例:

priority_queue< int, vector<int>, greater<int> >
priority_queue< int, list<int>, greater<int> >

标准库默认使用元素类型的<操作符来确定它们之间的优先级关系,用法有三:(下文转自http://www.cnblogs.com/vvilp/articles/1504436.html)

优先队列第一种用法,通过默认使用的<操作符可知在整数中元素大的优先级高。

priority_queue<int> qi; 

示例中输出结果为:9 6 5 3 2

优先队列第二种用法,建立priority_queue时传入一个比较函数,使用functional.h函数对象作为比较函数。

priority_queue<int, vector<int>, greater<int> >qi2;

示例2中输出结果为:2 3 5 6 9

优先队列第三种用法,是自定义优先级。

struct node 
{
     friend bool operator< (node n1, node n2)
     {
         return n1.priority < n2.priority;
     } 
     int priority;
     int value; 
}; 
priority_queue<node> qn; 

在示例3中输出结果为:

优先级  值

9          5

8          2

6          1

2          3

posted @ 2016-03-10 10:09  小德cyj  阅读(279)  评论(0编辑  收藏  举报