【C++从0到1-黑马程序员】STL容器(三)

本文详细介绍了C++STL中的List、Set和Map容器,包括它们的基本概念、构造方法、大小操作、插入删除、数据存储、反转排序以及Set与Multiset的区别。重点突出了这些容器的特点和使用技巧。
摘要由CSDN通过智能技术生成

6. List容器

6.1 基本概念

链表(list)是一种物理存储单元上非连续的存储结构,数据元素的逻辑顺序是通过链表中的指针链接实现的

功能:将数据进行链式存储

链表的组成:由一系列的结点构成

结点的组成:一个存储数据元素的数据域,另一个是存储下一个结点地址的指针域

STL中的链表是一个双向循环链表

由于链表的存储方式并不是连续的内存空间,因此链表中的迭代器支持前移和后移,属于双向迭代器。

优点:

  • 采用动态存储分配,不会造成内存浪费和溢出
  • 链表执行插入和删除操作十分方便,修改指针即可,不需要移动大量元素

缺点:空间(指针域)和时间(遍历)额外耗费较大

插入操作和删除操作都不会导致原有list迭代器的失效,在vector中是不成立的

6.2 构造函数

函数原型:

list v;                   // 采用模板实现类实现,默认构造函数

list(begin,end);          // 将[beg,end]区间中元素拷贝给本身

list(n,elem);             // 构造函数将n个elem拷贝给本身

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

6.3 赋值和交换

函数原型:

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

assign( beg, end );                    // 将[begin,end]区间中元素赋值给本身

assign( n, elem );                     // 将n个elem拷贝赋值给本身

swap(lst);                           // 将lst与本身交换

6.4 大小操作

函数原型:

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

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

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

resize(int num,elem);     // 重新制定容器的长度为num,若容器变长,则以elem值填充新位置;

                          // 若容器变短,则末尾超出容器长度元素被删除

6.5 插入和删除

两端插入操作:

push_back(ele);     // 尾部插入元素ele

push_front(ele);    // 头部插入元素ele

pop_back();         // 删除最后一个元素

pop_front();        // 删除第一个元素

指定位置操作:

insert(const_iterator pos,ele);         // 在pos插入一个ele元素的拷贝,返回新数据的位置

insert(const_iterator pos,int n,ele);   // 在pos插入n个ele元素的拷贝,返回新数据的位置

insert(const_iterator pos,begin,end);   // 在pos位置插入[begin,end]区间数据,无返回值

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

erase(const_iterator start,const_iterator end); // 删除[begin,end]区间数据,返回下一个数据位置
    
clear();                               // 删除容器中所有元素

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

6.6 数据存储

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

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

list不支持使用[]和at方式访问容器中的元素,原因是list本质是链表,不适用连续线性空间存储数据,迭代器也是不支持随机访问的

6.7 反转和排序

将容器中的元素反转,以及将容器中的数据进行排序

reverse(); // 反转链表

sort();    // 链表排序

所有不支持随机访问迭代器的容器,不可以用标准算法;不支持随机访问迭代器的容器,内部会提供对应的一些算法。

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

list<int>L;
L.sort(myCompare);

对于自定义数据类型,必须要指定排序规则,否则编译器不知道如何进行排序

高级排序只是在排序规则上再进行一次逻辑规则制定,并不复杂

7. Set容器

7.1 set基本概念

简 介: 所有元素都会在插入时自动被排序

本 质: set/multiset属于关联式容器,底层结构是用二叉树实现

set和multiset区别:set不允许容器中有重复的元素;multiset允许容器中有重复的元素

7.2 set构造和赋值

set容器插入数据时用insert

set容器插入数据的数据会自动排序

函数原型:
        
set v;                 // 采用模板实现类实现,默认构造函数

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

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

7.3 set大小和交换

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

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

swap(st);  // 将st与本身交换

7.4 set插入和删除

insert(elem);                 // 插入elem元素

clear();                      // 删除容器中所有元素

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

erase(const_iterator start,const_iterator end); // 删除[begin,end]区间数据,返回下一个数据位置

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

7.5 set查找和统计

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

count(key); // 统计key的元素个数,对于set,结果为1或0

7.6 set和multiset区别

  • set不可以插入重复数据,而multiset可以
  • set插入数据的同时会返回插入结果,表示插入是否成功
  • multiset不会检测数据,因此可以插入重复数据

7.7 pair对组创建

功能描述:

成对出现的数据,利用对组可以返回两个数据

两种创建方式:

pair p(value1,value2);

pair p = make_pair(value1,value2);

7.8 set排序

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

class MyCompare
{
public:
    bool operator()(int v1,int v2) const
    {
        return  v1 > v2;
    }
}

set<int,MyCompare> s;

8. Map容器

8.1 map基本概念

简 介:

  • map中所有元素都是pair
  • pair中第一个元素为key(键值),起到索引作用,第二个元素为value(实值)
  • 所有元素都会根据元素的键值自动排序

本 质:

  • map/multimap属于关联式容器,底层结构是用二叉树实现

优 点:

  • 可以根据key值快速找到value

map和multimap区别:

  • map不允许容器中有重复key元素
  • multimap允许容器中有重复key值元素

8.2 map构造和赋值

函数原型:

map mp;             // 默认构造函数

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

赋值:

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

// map中所有元素都是成对出现,插入数据时候要使用对组

8.3 map大小和交换

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

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

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

8.3 map插入和删除

insert(elem);                 // 插入elem元素

clear();                      // 删除容器中所有元素

erase(const_iterator pos);    // 删除pos位置数据,返回下一个元素的迭代器

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

erase(key);                   // 删除容器中键值为key的元素
// insert 4种方法
map<int,int> m;
m.insert(pair<int,int>(1,10));
m.insert(make_pair(2,20));
m.insert(map<int,int>::value_type(3,30));
m[4] = 40;    //不推荐用于插入,但可以用于key访问value

8.4 map查找和统计

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

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

8.5 map容器排序

利用仿函数,可以改变排序规则

// 排序
class MyCompare
{
public:
    bool operator()(int v1,int v2) const
    {
        // 降序
        return  v1 > v2;
    }
}

map<int,int,MyCompare> m;
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值