C++ STL 迭代器 容器 算法

STL介绍


STL(Standard Template Library),即标准模板库,是一个具有工业强度的,高效的C++程序库。它被容纳于C++标准程序库(C++ Standard Library)中。
该库包含了诸多在计算机科学领域里所常用的基本数据结构和基本算法。为广大C++程序员们提供了一个可扩展的应用框架,高度体现了软件的可复用性。
为了具有足够通用性,STL主要依赖于模板而不是封装,继承和虚函数(多态性)——OOP(object-oriented programming)的三个要素。

1.STL内容


STL中六大组件:

1)容器(Container),是一种数据结构,如list,vector,和deques ,以模板类的方法提供。为了访问容器中的数据,可以使用由容器类输出的迭代器;

3)算法(Algorithm),是用来操作容器中任何数据结构的数据的模板函数。例如,STL用sort()来对一个vector中的数据进行排序,用find()来搜索一个list中的对象,函数本身与他们操作的数据的结构和类型无关,因此他们可以在从简单数组到高度复杂容器的任何数据结构上使用;

4)仿函数(Function object)

5)迭代适配器(Adaptor)

6)空间配制器(allocator)

1.1 容器


STL中的容器有队列容器和关联容器,容器适配器(congtainer adapters:stack,queue,priority queue),位集(bit_set),串包(string_package)等等。

  • 1)队列容器(Sequence containers),每个元素都有固定位置--取决于插入时机和地点,和元素值无关,vector、deque、list
    • Vectors:将元素置于一个动态数组中加以管理,可以随机存取元素(用索引直接存取),数组尾部添加或移除元素非常快速。但是在中部或头部安插元素比较费时;
    • Deques:是“double-ended queue”的缩写,可以随机存取元素(用索引直接存取),数组头部和尾部添加或移除元素都非常快速。但是在中部或头部安插元素比较费时;
    • Lists:双向链表,不提供随机存取(按顺序走到需存取的元素,O(n)),在任何位置上执行插入或删除动作都非常迅速,内部只需调整一下指针;
  • 2)关联式容器(Associated containers),元素位置取决于特定的排序准则,和插入顺序无关,set、multiset、map、multimap
    • Sets/Multisets:内部的元素依据其值自动排序,Set内的相同数值的元素只能出现一次,Multisets内可包含多个数值相同的元素,内部由二叉树实现,便于查找;
    • Maps/Multimaps:Map的元素是成对的键值/实值,内部的元素依据其值自动排序,Map内的相同数值的元素只能出现一次,Multimaps内可包含多个数值相同的元素,内部由二叉树实现,便于查找;
      容器类自动申请和释放内存,无需new和delete操作。vector基于模板实现,需包含头文件vector。
//1.定义和初始化
    vector<int> vec1;    //默认初始化,vec1为空
    vector<int> vec2(vec1);  //使用vec1初始化vec2
    vector<int> vec3(vec1.begin(),vec1.end());//使用vec1初始化vec2
    vector<int> vec4(10);    //10个值为的元素
    vector<int> vec5(10,4);  //10个值为的元素
//2.常用操作方法
    vec1.push_back(100);            //添加元素
    int size = vec1.size();         //元素个数
    bool isEmpty = vec1.empty();    //判断是否为空
    cout<<vec1[0]<<endl;        //取得第一个元素
    vec1.insert(vec1.end(),5,3);    //从vec1.back位置插入个值为的元素
    vec1.pop_back();              //删除末尾元素
    vec1.erase(vec1.begin(),vec1.end());//删除之间的元素,其他元素前移
    cout<<(vec1==vec2)?true:false;  //判断是否相等==、!=、>=、<=...
    vector<int>::iterator iter = vec1.begin();    //获取迭代器首地址
    vec1.clear();                 //清空元素
//3.遍历
    //下标法
    int length = vec1.size();
    for(int i=0;i<length;i++)
    {
       cout<<vec1[i];
    }
    cout<<endl<<endl;
    //迭代器法
    vector<int>::const_iterator iterator = vec1.begin();
    for(;iterator != vec1.end();iterator++)
    {
       cout<<*iterator;
    }

1.2 迭代器


迭代器是连接容器算法的一种重要桥梁。就是一种智能指针。它对原始指针进行了封装,而且提供一些等价于原始指针的操作,做到既方便又安全。
容器的迭代器都是定身制作的,什么意思呢?全部容器都内置一个迭代器。该内置迭代器由容器的设计者实现。
常见的一些迭代器类型:iterator、const_iterator、reverse_iterator和const_reverse_iterator

iterator:
迭代器iterator 提供了一种一般化的方法对顺序或关联容器类型中的每个元素进行连续访问

例如,假设iter为任意容器类型的一个iterator,
++iter 表示向前移动迭代器使其指向容器的下一个元素,
*iter返回iterator 指向元素的值,
每种容器类型都提供一个begin()和一个end()成员函数。

begin()返回一个iterator 它指向容器的第一个元素

end()返回一个iterator 它指向容器的末元素的下一个位置

#include <iostream>  
#include <vector>  
using namespace std;  
int main()  
{  
    vector<int> v;  
    v.push_back(3);  //数组尾部插入3  
    v.push_back(2);  
    v.push_back(1);  
    v.push_back(0);  
    cout << " 下标 " << v[3] << endl;  
    cout << " 迭代器 " << endl;  
    for(vector<int>::iterator i = v.begin();i!= v.end();++i)  
    {  
        cout << *i << " ";  
    }  
    cout << endl;  
    //在第一个元素之前插入111  insert begin+n是在第n个元素之前插入  
    v.insert(v.begin(),111);  
    //在最后一个元素之后插入222 insert end + n 是在n个元素之后插入  
    v.insert(v.end(),222);  
    for(vector<int>::iterator i = v.begin();i!= v.end();++i)  
    {  
        cout << *i << " ";  
    }  
    cout << endl;  

    vector<int> arr(10);  
    for(int i = 0; i < 10; i++)  
    {  
        arr[i] = i;  
    }  
    for(vector<int>::iterator i = arr.begin();i!= arr.end();++i)  
    {  
        cout << *i << " ";  
    }  
    cout << endl;  
    //删除 同insert  
    arr.erase(arr.begin());  
    for(vector<int>::iterator i = arr.begin();i!= arr.end();++i)  
     {  
        cout << *i << " " ;  
     }  
    cout << endl ;  
    arr.erase(arr.begin(),arr.begin()+5);  
    for(vector<int>::iterator i = arr.begin();i!= arr.end();++i)  
    {  
        cout << *i << " " ;  
    }  
    cout << endl ;  
    return 0 ;  
 }  

1.3算法


  • algorithm>是所有STL头文件中最大的一个(尽管它很好理解),它是由一大堆模版函数组成的,可以认为每个函数在很大程度上都是独立的,其中常用到的功能范围涉及到比较、交换、查找、遍历操作、复制、修改、移除、反转、排序、合并等等。
  • numeric>体积很小,只包括几个在序列上面进行简单数学运算的模板函数,包括加法和乘法在序列上的一些操作。
  • functional>中则定义了一些模板类,用以声明函数对象。
#include<iostream>  
#include<vector>  
#include<algorithm>  
using namespace std;  
int main()  
{  
    vector<int> v;  
    for(int i = 0; i < 10; ++i)  
    {  
        v.push_back(i);  
    }  
    for(vector<int>::iterator it = v.begin(); it != v.end(); ++it)  
    {  
        cout << *it << " ";  
    }  
    cout << endl;  
    reverse(v.begin(),v.end());  //倒序函数
    for(vector<int>::iterator it = v.begin(); it != v.end(); ++it)  
    {  
        cout << *it << " ";  
    }  
    cout << endl;  
    return 0; 

STL中算法大致分为四类:

  • 1)非可变序列算法:指不直接修改其所操作的容器内容的算法。
  • 2)可变序列算法:指可以修改它们所操作的容器内容的算法。
  • 3)排序算法:对序列进行排序和合并的算法、搜索算法以及有序序列上的集合操作。
  • 4)数值算法:对容器内容进行数值计算。

2.迭代器 具体分析


#include<iostream>
#include<algorithm>//用到find函数
#include<vector>
using namespace std;
int main()
{
    vector<int>vec;
    int i;
    for(i=0;i<10;i++)
    {
        vec.push_back(i);
    }
    if(vec.end()!=find(vec.begin(),vec.end(),7))
    {
        cout<<"find!"<<endl;
    }
    else
    {
        cout<<"not find!"<<endl;
    }
    system("pause");
    return 0;
}

上述代码中。值得注意的是用到的find函数,find函数的函数原型为:template

#include<iostream>
using namespace std;
class A{};
class A1:public A{};//类A1继承A
class B{};
void print(A)//仅仅需指定參数类型
{
    cout<<"This is Base class A!"<<endl;
}
void print(B)//仅仅需指定參数类型
{
    cout<<"This is Base class B!"<<endl;
}
int main()
{
    print(A());
    print(B());
    print(A1());//将一个派生类的对象传递过去
    return 0;
}

从上面的代码能够看出,在main函数中,我们调用print(A1())。即能够用派生类对象作为实參传递给以基类类型作为形參的函数。所以find函数中的vec.begin()作为实參,以输入迭代器类型作为形參,两者能够达到虚实相结合的目的而不会出错。所以说。迭代器为各类算法和和各类容器提供了一个相互沟通的平台。

ref

https://blog.csdn.net/qq_23100787/article/details/51388163
https://www.cnblogs.com/lhuan/p/5706654.html

猜你喜欢

转载自blog.csdn.net/qq_35608277/article/details/80290398