【C++成长之路】C++ STL(3)

前言

    认识STL相关容器


各大容器的特点:
1.可以用下标访问的容器有(既可以插入也可以赋值):vector、deque、map;

特别要注意一下,vector和deque如果没有预先指定大小,是不能用下标法插入元素的!

2. 序列式容器才可以在容器初始化的时候制定大小,关联式容器不行;

3.注意,关联容器的迭代器不支持it+n操作,仅支持it++操作。

                                                          序列式容器:
一、vector
当需要使用数组的情况下,可以考虑使用vector

 1.特点:

 (1) 一个动态分配的数组(当数组空间内存不足时,都会执行: 分配新空间-复制元素-释放原空间);

 (2) 当删除元素时,不会释放限制的空间,所以向量容器的容量(capacity)大于向量容器的大小(size);

 (3) 对于删除或插入操作,执行效率不高,越靠后插入或删除执行效率越高;

 (4) 高效的随机访问的容器。

 2.创建vecotr对象:

 (1) vector<int> v1;

 (2) vector<int> v2(10);  

 3.基本操作:

 v.capacity();  //容器容量

 v.size();      //容器大小

 v.at(int idx); //用法和[]运算符相同

 v.push_back(); //尾部插入

 v.pop_back();  //尾部删除

 v.front();     //获取头部元素

 v.back();      //获取尾部元素

 v.begin();     //头元素的迭代器

 v.end();       //尾部元素的迭代器

 v.insert(pos,elem); //pos是vector的插入元素的位置

 v.insert(pos, n, elem) //在位置pos上插入n个元素elem

 v.insert(pos, begin, end);

 v.erase(pos);   //移除pos位置上的元素,返回下一个数据的位置

 v.erase(begin, end); //移除[begin, end)区间的数据,返回下一个元素的位置

 reverse(pos1, pos2); //将vector中的pos1~pos2的元素逆序存储

二分查找
#include<iostream>

#include<algorithm>

#include<vector>

#include<deque>

#include<map>

#include<cstring>

using namespace std;

int  main()

{

    vector<int> v(10);

    int num;

    vector<int>::iterator beg = v.begin();

    vector<int>::iterator end = v.end();

    vector<int>::iterator mid = v.begin() + (end - beg) / 2;

    for (int i = 0; i < 10; i++)

    {

         v[i] = i;

    }

    cin >> num;

    sort(v.begin(), v.end());

    while (*mid != num &&  beg <= end)

    {

         if (num < *mid)

         {

             end = mid;

         }

         else

         {

             beg = mid + 1;

         }

         mid = beg + (end - beg) / 2;

    }

    if (*mid == num)

    {

         cout << "Find" << endl;

    }

    else

    {

         cout << "Not Find" << endl;

    }

    return 0;

}

 二、deque
1.特点:

(1) deque(double-ended queue 双端队列);

(2) 具有分段数组、索引数组, 分段数组是存储数据的,索引数组是存储每段数组的首地址;

(3) 向两端插入元素效率较高!

    (若向两端插入元素,如果两端的分段数组未满,既可插入;如果两端的分段数组已满,

    则创建新的分段函数,并把分段数组的首地址存储到deque容器中即可)。

    中间插入元素效率较低!

2. 创建deque对象

(1) deque<int> d1;

(2) deque<int> d2(10);

3. 基本操作:

(1) 元素访问:

d[i];

d.at[i];

d.front();

d.back();

d.begin();

d.end();

(2) 添加元素:

d.push_back();

d.push_front();

d.insert(pos,elem); //pos是vector的插入元素的位置

d.insert(pos, n, elem) //在位置pos上插入n个元素elem

d.insert(pos, begin, end);

(3) 删除元素:

d.pop_back();

d.pop_front();

d.erase(pos);   //移除pos位置上的元素,返回下一个数据的位置

d.erase(begin, end); //移除[begin, end)区间的数据,返回下一个元素的位置

三、list
1. 特点:

(1) 双向链表

2.创建对象:

list<int> L1;

list<int> L2(10);

3.基本操作:

(1) 元素访问:

lt.front();

lt.back();

lt.begin();

lt.end();

(2) 添加元素:

lt.push_back();

lt.push_front();

lt.insert(pos, elem);

lt.insert(pos, n , elem);

lt.insert(pos, begin, end);

lt.pop_back();

lt.pop_front();

lt.erase(begin, end);

lt.erase(elem);

(3)sort()函数、merge()函数、splice()函数:

sort()函数就是对list中的元素进行排序;

merge()函数的功能是:将两个容器合并,合并成功后会按从小到大的顺序排列;

比如:lt1.merge(lt2); lt1容器中的元素全都合并到容器lt2中。

splice()函数的功能是:可以指定合并位置,但是不能自动排序!

这些函数用到的次数较少,要用时再加深印象!!!

                                                            关联式容器:
1. 特点:
(1) 关联式容器都是有序的,升序排列,自动排序;

(2) 实现的是一个平衡二叉树(红黑树),每个元素都有一个父节点和两个子节点,

左子树的所有元素都比自己小,右子树的所有元素都比自己大;

四、set/multiset
1. 特点:

构造set集合的主要目的是为了快速检索,去重与排序

(1) set存储的是一组无重复的元素,而multiset允许存储有重复的元素;

(2) 如果要修改某一个元素值,必须先删除原有的元素,再插入新的元素。

2.创建对象:

set<T> s;

set<T, op(比较结构体)> s;     //op为排序规则,默认规则是less<T>(升序排列),或者是greater<T>(降序规则)。

函数对象:

class Sum

{

public:

    int operator()(int a, int b){return a+b;}

};

Sum sum;  //利用了()运算符的重载

3. 基本操作:

s.size();      //元素的数目

s.max_size();  //可容纳的最大元素的数量

s.empty();     //判断容器是否为空

s.find(elem);  //返回值是迭代器类型

s.count(elem); //elem的个数,要么是1,要么是0,multiset可以大于一

s.begin();

s.end();

s.rbegin();

s.rend();

s.insert(elem);

s.insert(pos, elem);

s.insert(begin, end);

s.erase(pos);

s.erase(begin,end);

s.erase(elem);

s.clear();//清除a中所有元素;

pair类模板
1. 主要作用是将两个数据组成一个数据,用来表示一个二元组或一个元素对,

两个数据可以是同一个类型也可以是不同的类型。

当需要将两个元素组合在一起时,可以选择构造pair对象,

set的insert返回值为一个pair<set<int>::iterator,bool>。bool标志着插入是否成功,而iterator代表插入的位置,若该键值已经在set中,则iterator表示已存在的该键值在set中的位置。
如:set<int> a;

           a.insert(1);

           a.insert(2);

           a.insert(2);//重复的元素不会被插入;

注意一下:make_pair()函数内调用的仍然是pair构造函数
 

set中的erase()操作是不进行任何的错误检查的,比如定位器的是否合法等等,所以用的时候自己一定要注意。

创建pair对象:

pair<int, float> p1;   //调用构造函数来创建pair对象

make_pair(1,1.2);      //调用make_pair()函数来创建pair对象

pair对象的使用:

pair<int, float> p1(1, 1.2);

cout<< p1.first << endl;

cout<< p1.second << endl;

顺序遍历:
set<int> a;

set<int>::iterator it=a.begin();

for(;it!=a.end();it++)

    cout<<*it<<endl;

反序遍历:
set<int> a;

set<int>::reverse_iterator rit=a.rbegin();

for(;rit!=a.rend();rit++)

cout<<*rit<<endl;

find(key_value);//如果找到查找的键值,则返回该键值的迭代器位置,否则返回集合最后一个元素后一个位置的迭代器,即end();
如:int b[]={1,2,3,4,5};     set<int> a(b,b+5);

        set<int>::iterator it;

        it=a.find(3);

        if(it!=a.end())  cout<<*it<<endl;

        else cout<<“该元素不存在”<<endl;

        it=a.find(10);

        if(it!=a.end())  cout<<*it<<endl;

        else cout<<“该元素不存在”<<endl;
 

总结

学习STL相关容器

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值