STL常见容器和算法

 

目录

vector容器

deque容器

stack容器

queue容器

List容器

set/multiset容器

map/multimap容器

STL-函数对象

STL 常用算法


 
  

vector容器

与数组类似,也称为单端数组,vector可以动态扩展,空间满后,寻找更大的新空间,将原有数组拷贝到新空间

vector迭代器支持随机访问

vector构造函数

无参构造

通过输入迭代器的区间进行构造

通过n个elm进行构造

拷贝构造

vector赋值操作

vector& operator=(const vector &vec);  //重载等号
​
assign(beg,end);    //将[beg,end)的数据(此处还是指迭代器范围)拷贝赋值给本身
​
assign(n,elem);     //将n个elem赋值给自身

assign()理解为会把之前所有的值删除,然后赋参数列表里的值,与等号的作用等价

vector容量和大小

empty(); //判断容器是否为空
capacity(); //容器的容量
size(); //容器的大小
resize();   //重新指定大小,如果重新指定的大小比原来长,默认用0填充
            //如果重新指定的大小比原来小,会删除超出部分元素

vector插入和删除

push_back(ele);
pop_back();
insert(const_iterator pos,ele); //在迭代器位置插入元素
insert(const_iterator pos,count,ele);//在迭代器位置插入n个元素
erase(const_iterator pos);//删除指定位置
erase(const_iterator beg,const_iterator end);//删除指定范围,若范围为begin()和end(),等价于清空                                           
clear();//清空容器内容

vector数据存取

at(int idx);    //返回索引idx所指的数据
operator[];     //返回索引idx所指的数据
front();        //返回容器中第一个数据元素
back();         //返回最后一个元素

除了迭代器,也可以用 []at() 等进行访问vector中的元素

vector互换容器

实现两个容器内元素进行互换

swap();

巧用swap()可以收缩内存:

vector(v).swap(v);
//vector(v)   申请了一个匿名对象,内容用v拷贝
//匿名对象会在执行完语句后释放

vector预留空间

减少vector在动态扩展容量时的扩展次数

reserve(int space);     //若数据量较大,预留空间可以减少动态扩展的次数

deque容器

deque容器的基本概念

  • 双端数组,也可以对头端进行插入删除操作

vector对于头部的数据插入删除效率低,需要移动大量元素

  • 工作原理:

    deque容器内部有个中控器,维护每段缓冲区中的内容,缓冲区中存放真实数据

    中控器维护的是每个缓冲区的地址,使得使用deque时像一片连续的内存空间

deque构造函数

dequedeq; //默认构造

deque(beg,end); //将迭代器[beg,end)区间中的元素拷贝给本身

deque(n,elem); //构造函数将n个elem传入本身

deque(const deque &deq); //拷贝构造函数

补充一点:函数参数是容器,且要加const修饰时,迭代器也要改为const_iterator

deque容器赋值操作

deque& operator=(const deque &deq); //重载等号

assign(beg,end); //通过另一个容器范围内的值进行赋值

assign(n,ele); //n个ele元素进行赋值

assign()理解为会把之前所有的值删除,然后赋参数列表里的值,与等号的作用等价

deque容器大小操作

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

deque.size() //返回容器的大小

deque.resize(n) //重新指定大小,若比原来长,默认0填充

//若比原来短,相当于删除末尾元素

deque容器插入和删除

  • 两端插入和删除

    push_back(elem); //尾插

    push_front(elem); //头插

    pop_back() //尾删

    pop_front() //头删

  • 指定位置操作

    insert(const_iterator pos,elem); //pos位置插入一个elem元素的拷贝,返回新元素的位置(数据类型为迭代器类型)

    insert(const_iterator pos,n,elem); //pos位置插入n个elem元素的拷贝,无返回值

    insert(pos,beg,end); //pos位置插入[beg,end)区间的值,无返回值,相比vector多了此重载版本

    clear(); //清空deque

    erase(beg,end); //删除[beg,end)区间内的值,返回下一个数据值位置

    erase(pos); //删除pos位置的值,返回下一个数据的位置

deque容器数据存取

at(int idx); //返回索引idx所指的数据

operator[]; //重载[],返回索引idx所指的元素

front(); //返回容器中第一个数据元素

back(); //返回容器中最后一个数据元素

除了迭代器,也可以用 []at() 等进行访问deque中的元素

deque容器排序操作

sort(iterator beg,iterator end); //对区间内的元素进行排序

stack容器

基本概念

  • 先进后出,只有一个出口

  • 栈不允许有遍历行为,只能访问栈顶元素

stack常用接口

构造函数

stack stk; //默认构造

stack(const stack &stk); //拷贝构造函数

赋值操作

stack& operator=(const stack &stk); //重载等号操作符

数据存取

push(elm); //向栈顶添加元素

pop(); //移除栈顶元素

top(); //返回栈顶元素

大小操作:

empty(); //判断栈是否为空

size(); //返回栈的大小

queue容器

队列(queue)是一种先进先出的数据结构,一端只能出队,一端只能入队,只能访问队头和队尾元素,不允许遍历行为

queue容器常用接口

构造函数

queue que; //模板类实现,默认构造

queue(const queue &que); //拷贝构造函数

赋值操作

queue& operator=(const queue &que); //重载等号运算符

数据存取

push(elem); //队尾添加元素

pop(); //移除队头元素

back(); //返回最后一个元素

front(); //返回第一个元素

大小操作

empty(); //判断是否为空

size(); //返回队列大小

List容器

基本概念

链表,使用非连续的内存地址,将数据进行链式存储,由一系列结点构成

STL中的List链表是双向循环链表,链表的存储方式并不是连续的内存空间,其迭代器只支持前移和后移,属于双向迭代器

插入和删除不会造成list 迭代器的失效,这在vector中不成立

list构造函数

list lst; //模板类实现,默认构造

list(beg,end); //将迭代器[beg,end)区间 元素拷贝给自身

list(n,elem); //将n个elem 拷贝给自身

list(const list &lst); //拷贝构造函数

list赋值和交换

assign(beg,end); //将迭代器[beg,end)范围内的数拷贝赋值给本身

assign(n,elem); //赋值n个elem

list& operator=(const list &lst); //重载等号

swap(lst); //将lst与本身的元素互换,即使长度不同也可以互换

list大小操作

empty();

size();

resize(num); //重新指定list的长度为num,若容器边长,则以默认值填充新位置

//若变短,则删除超出长度的元素

resize(num,elem);

list插入和删除

push_back(elem); //尾插

push_front(elem); //头插

pop_back() //尾删

pop_front() //头删

insert(const_iterator pos,elem); //pos位置插入一个elem元素的拷贝,返回新元素的位置(数据类型为迭代器类型)

insert(const_iterator pos,n,elem); //pos位置插入n个elem元素的拷贝,无返回值

insert(pos,beg,end); //pos位置插入[beg,end)区间的值,无返回值,相比vector多了此重载版本

clear(); //清空

erase(beg,end); //删除[beg,end)区间内的值,返回下一个数据值位置

erase(pos); //删除pos位置的值,返回下一个数据的位置

remove(elem); //删除容器中所有与elem值匹配的元素

list的迭代器不支持随机访问,只能++或--,因为双向链表只知道当前结点的前驱和后继,再往后的结点就得访问其他结点才知道

list数据存取

front(); //返回第一个元素

back(); //返回最后一个元素

无法重载[],也无法使用at(),因为list不是连续的内存空间

list反转和排序

reverse(); //实现链表的反转

关于排序,list容器不能直接使用algorithm提供的sort(),所有不支持随机访问迭代器的容器,都不可以用标准算法

list内部提供了sort()成员函数

sort()默认为升序排序,若要为降序,需要提供比较器

bool myCompare(int v1,int v2)
{
    return v1 > v2 ;
}

例:自定义数据类型Person,按照年龄升序,身高降序排列,需要提供:

bool comparePerson(Person &p1,Person &p2){	if(p1.m_Age==p2.m_Age)        return p1.m_Height>p2.m_Height;    return p1.m_Age 
  

set/multiset容器

基本概念

所有元素都会在插入时自动被排序,set/multiset 属于关联式容器,底层用二叉树实现

set/multiset区别:

set不允许容器中有重复元素,multiset允许容器中有重复的元素

set构造和赋值

set st; //默认构造

set(const set &st); //拷贝构造

set& operator=(const set &st) //重载等号操作符

set插入数据只有insert()方式

set大小和交换

size(); //返回容器中元素的数目

empty(); //判断是否为空

swap(); //交换两个集合容器

set插入和删除

insert(); //插入元素

clear(); //清空

erase(pos); //删除pos迭代器所指的元素,返回下一个元素的迭代器

erase(beg,end); //删除区间[beg,end)的所有元素,返回下一个元素的迭代器

erase(elem); //删除容器中值为elem的元素

set查找和统计

find(key); //查找key是否存在,若存在,返回该元素的迭代器,若不存在,返回set.end()

count (key); //返回key的元素个数

set和multiset区别

set插入数据的同时会返回插入结果,表示插入是否成功

multiset不会检测数据重复性,因此可以插入重复数据

pair对组创建

成对出现的数据,利用对组可以返回两个数据,使用对组不需要包含头文件

pair p (value1,value2);

pair p = make_pair(value1,value2);

set容器排序

set默认排序规则为从小到大,利用仿函数可以改变排序规则

存放内置数据类型的情况:

//仿函数:class myCompare{public:    bool operator()(int v1,int v2){		return v1>v2;    }	};//创建set容器set st;

存放自定义数据类型的情况:

class Person{public:    Person(string name,int age)    {        this->m_Name=name;        this->m_Age=age;    }    string m_Name;    int m_Age;};//对于自定义数据类型,set容器需要通过仿函数指定排序规则class ComparePerson{public:    bool operator()(const Person& p1,const Person& p2)    {        return p1.m_Age > p2.m_Age;		//降序排列    }};set st;

map/multimap容器

基本概念

map中所有元素都是pair,pair中第一个元素为key值(键值),起索引作用,第二个值为value(实值)

所有元素都会根据元素的键值自动排序

map/multimap是关联式容器,底层用二叉树实现,根据key可以快速找到value值

map不允许有重复的key值元素,multimap允许容器有重复key值元素

map构造和赋值

构造

map(T1,T2)mp; //默认构造

map(const map &mp); //拷贝构造

赋值

map& operator=(const map &mp); //重载等号

map中所有数据都是成对出现,插入数据时要用对组pair

map大小和交换

size(); //返回容器中元素的数目

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

swap(); //交换两个map容器

map插入和删除

insert(elem) //在容器中插入元素,此处元素是pair

clear(); //清空map

erase(pos); //删除迭代器所指的元素,返回下一个元素的迭代器

erase(beg,end); //删除区间[beg,end)的元素,返回下一个元素的迭代器

erase(key); //删除容器中值为key的元素

map内部重载了[],可以用key通过中括号访问value

mapm;m.insert(make_pair(1,10));m.insert(pair(2,20));m.insert(map::value_type(3,30));

map查找和统计

find(key); //查找key是否存在,返回该键的元素的迭代器,弱不存在返回map.end()

count(key); //统计key的元素个数

map排序

改变排序顺序,或者对自定义数据类型排序,需要提供仿函数

STL-函数对象

概念

重载函数调用操作符()的类,其对象称为函数对象

函数对象使用重载的()时,行为类似函数调用,也叫仿函数

调用

  • 函数对象在使用时,可以像普通函数一样调用,可以有参数,可以有返回值

//创建class Myadd{public:    int operator()(int v1,int v2)    {		return v1+v2;    }};//调用Myadd add;add(1,2);

  • 函数对象超出普通函数的概念,函数对象可以有自己的状态

例:可以在类内添加count属性,统计函数对象调用次数

  • 函数对象可以作为参数传递

谓词

  • 谓词概念

    返回bool类型的仿函数称为谓词,如果operator()接收一个参数,称为一元谓词,如果接收两个参数,称为二元谓词

内建函数对象

STL内建了一些函数对象,包括:

  • 算术仿函数

  • 关系仿函数

  • 逻辑仿函数

需要包含头文件#include

算术仿函数

negate是一元运算,其他都是二元运算

negate neg;
int a=neg(50);  //a的结果为-50
plusp;
a=p(10,20);    //a的结果为30
minusm;
a=m(10,20);    //a的结果为-10

关系仿函数

equal_tonot_equal_togreatergreater_equallessless_equal

逻辑仿函数

logical_andlogical_orlogical_not

STL 常用算法

常用遍历算法

for_each //遍历容器

for_each(iterator beg,iterator end,_func);

第三个参数可以是函数,也可以是函数对象

transform //搬运容器到另一个容器中

transform(iterator beg1,ierator end1,ierator beg2,_func);

//参数:原迭代器begin,原迭代器end,目标迭代器begin,函数或函数对象

注意,目标容器需要提前开辟空间(使用resize

常用查找算法

  • find //查找指定元素,返回指定元素的迭代器,未找到返回结束迭代器end()

    find(iterator beg,iterator end,value);

    find查找自定义数据类型时,需要重载==

  • find_if //按条件查找元素

    find_if(iterator beg,iterator end,_Pred);

    //参数:迭代器begin,迭代器end,谓词(bool类型仿函数)

  • adjacent_find //查找相邻重复元素

    adjacent_find(iterator beg,iterator end);

    //beg 开始迭代器,end 结束迭代器 查找相邻重复元素,返回相邻元素的第一个位置的迭代器

  • binary_search //查找指定元素是否存在

    bool binary_search(iterator beg,iterator end,value);

    //查找指定的元素,查到返回true,否则返回false

注意:binary_search只能用于有序序列

  • count //统计元素的个数

    count(iterator beg,iterator end,value);

    //对于自定义数据类型需要重载==

  • count_if //按条件统计元素个数

    count_if(iterator beg,iterator end,_Pred)

    //参数:迭代器begin,迭代器end,谓词(bool类型仿函数)

总结:对于自定义数据类型,需要重载符号,或提供一个谓词

常用排序算法

  • sort //对容器内元素进行排序

    sort(iterator beg,iterator end,_Pred);

    //修改排序规则或对于自定义数据类型需要提供谓词

  • random_shuffle //随机打乱容器中元素的顺序

    random_shuffle(iterator beg,iterator end);

    //如果要每次随机结果不同,需要加上随机数种子

  • merge //将两个容器元素合并,并存储到另一容器,但两个容器必须是有序的(等同于归并排序的merge过程)

    merge(ierator beg1,iterator end1,iterator beg2,ierator end2,ierator dest);

    //beg1,end1,容器1的开始/结束迭代器

    //beg2,end2,容器2的开始/结束迭代器

    //dest,目标容器的开始迭代器

    //dest容器需要使用resize()预先分配内存

  • reverse //将容器内元素进行反转

    reverse(iterator beg,iterator end);

常用拷贝和替换算法

  • copy //容器内指定范围的元素拷贝到另一容器中

    copy(iterator beg,iterator end,iterator dest);

    //beg,end,容器的开始/结束迭代器

    //dest,目标容器的开始迭代器

    //dest容器需要使用resize()预先分配内存

    //相比于copytransform更灵活,可以自定义函数或者函数对象,在搬运时对数据进行操作

  • replace //将容器内指定范围的旧元素修改为新元素

    replace(iterator beg,iterator end,old_value,new_value);

    //beg,end,容器的开始/结束迭代器

    //old_value,new_value,旧元素/新元素

  • replace_if //将区间内满足条件的元素,替换成指定元素

    replace_if(iterator beg,iterator end,_Pred,newvalue)

    //beg,end,容器的开始/结束迭代器

    //_Pred 谓词

    //newvalue 替换的新元素

  • swap //替换两个同类型容器的元素

常用算术生成算法

算术生成算法属于小型算法,使用时包含的头文件为

  • accumulate //计算容器元素累计总和

    accumulate(iterator beg,iterator end,value);

    //beg,end,容器的开始/结束迭代器

    //value,累加起始值,不需要起始值写0就可以

  • fill //向容器内填充指定的元素

    fill(iterator beg,iterator end,value);

    //beg,end,容器的开始/结束迭代器

    //value,填充的值

    若是新建的容器,需要用resize预先指定其大小

常用集合算法

  • set_intersection //求两个集合的交集

    iterator set_intersection(iterator beg1,iterator end1,iterator beg2,iterator end2,iterator dest);

    //目标容器需要用resize提前开辟空间

    //set_intersection会返回交集end位置的迭代器

  • set_union //求两个集合的并集

    set_union(iterator beg1,iterator end1,iterator beg2,iterator end2,iterator dest);

    //目标容器需要用resize提前开辟空间

    //set_union会返回并集end位置的迭代器

  • set_difference //求两个容器的差集

    set_difference(iterator beg1,iterator end1,iterator beg2,iterator end2,iterator dest);

    //目标容器需要用resize提前开辟空间

    //set_diference会返回并集end位置的迭代器

你可能感兴趣的:(c++,stl)