C++进阶编程 --- 3(下).queue容器、list容器、set / multiset容器、map / multimap容器

第三章(下):

3.STL 常用容器

3.6 queue容器
3.6.1 queue基本概念

Queue是一种先进先出的数据结构,有两个出口

  • 队列容器允许从一端新增元素,从另一端移除元素

  • 队列中只有队头和队尾才可被外界所使用,因此队列不允许有遍历操作

在这里插入图片描述

3.6.2 queue常用接口

作用:常用对外接口

构造函数 - 函数原型:

queue<T> que;                         //采用模板类实现,默认构造函数
  • queue(const queue &que); //拷贝构造函数

赋值操作 - 函数原型:

  • queue& operator=(const queue &que); //重载等号操作符

数据存取 - 函数原型:

  • push(elem); //往队尾新增元素

  • pop(); //从队头移除第一个元素

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

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

大小操作 - 函数原型:

  • empty(); //返回队列是否为空

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

#include <iostream>
using namespace std;
#include <queue>

class Student
{
public:
    Student(string name, int age)
    {
        this->m_Name = name;
        this->m_Age = age;
    }
    string m_Name;
    int m_Age;
};

void test01()
{
    queue<Student>q;

    Student s1("小明", 18);
    Student s2("小红", 19);
    Student s3("小王", 20);

    //入队
    q.push(s1);
    q.push(s2);
    q.push(s3);

    cout << "队列的大小为:" << q.size() << endl;

    //出队
    while (!q.empty())
    {
        cout << "队头元素" << endl;
        cout << "姓名:" << q.front().m_Name << " 年龄:" << q.front().m_Age << endl;

        cout << "队尾元素" << endl;
        cout << "姓名:" << q.back().m_Name << " 年龄:" << q.back().m_Age << endl;

        q.pop();
    }
}

int main()
{
    test01();
    system("pause");
    return 0;
}
3.7 list容器
3.7.1 list基本概念

作用:将数据进行链式存储

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

链表是由一系列结点所组成

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

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

链表的存储方式并不是连续的内存空间,所以链表的list迭代器只支持前移和后移,属于双向迭代器

在这里插入图片描述

list优点

  • 采用动态存储分配,不会造成内存浪费和溢出

  • 插入和删除操作十分便捷,只需修改指针,无需移动大量元素

list缺点

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

注意:list插入和删除操作都不会给原有list迭代器造成失效

3.7.2 list构造函数

作用:创建list容器

函数原型

list<T> lst;            //采用模板类实现,默认构造函数
  • list(beg, end); //[beg, end)区间内的元素拷贝给自身

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

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

#include <iostream>
using namespace std;
#include <list>

void printList(list<int>& l)
{
    for (list<int>::iterator it = l.begin(); it != l.end(); it++)
    {
        cout << *it << " ";
    }
    cout << endl;
}

void test01()
{
    list<int>L1;
    L1.push_back(10);
    L1.push_back(20);
    L1.push_back(30);
    L1.push_back(40);

    printList(L1);

    list<int>L2(L1.begin(), L1.end());
    printList(L2);

    list<int>L3(10, 10);
    printList(L3);

    list<int>L4(L3);
    printList(L4);
}

int main()
{
    test01();
    system("pause");
    return 0;
}
3.7.3 list赋值和交换

作用:给list容器进行赋值,交换list容器

函数原型

  • assign(beg, end); //[beg, end)区间内的元素拷贝赋值给自身

  • assign(n, elem); //n个elem拷贝赋值给自身

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

  • swap(lst); //lst与自身元素互换

#include <iostream>
using namespace std;
#include <list>

void printList(list<int>& l)
{
    for (list<int>::iterator it = l.begin(); it != l.end(); it++)
        {
            cout << *it << " ";
        }
    cout << endl;
}

void test01()
{
    list<int>L1;
    L1.push_back(10);
    L1.push_back(20);
    L1.push_back(30);
    L1.push_back(40);
    L1.push_back(50);
    printList(L1);

    list<int>L2(L1.begin(),L1.end());
    printList(L2);

    list<int>L3(10, 10);
    printList(L3);

    list<int>L4;
    L4 = L3;
    printList(L4);

    list<int>L5;
    L5.assign(10, 20);
    cout << "swap - before" << endl;
    printList(L3);
    printList(L5);

    L3.swap(L5);
    cout << "swap - after" << endl;
    printList(L3);
    printList(L5);
}

int main()
{
    test01();
    system("pause");
    return 0;
}
3.7.4 list大小操作

作用:list容器大小进行操作

函数原型

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

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

  • resize(num);
    //重新指定容器长度为num,如果容器变长,则以默认值填充新位
    //如果容器变短,则末尾超出容器长度的元素将被删除

  • resize(num, elem);

     //重新指定容器长度num,如容器变长,则以elem填充新位置
    
     //如容器变短,则末尾超出容器长度的元素将被删除
    
#include <iostream>
using namespace std;
#include <list>

void printList(list<int>& l)
{
    for (list<int>::iterator it = l.begin(); it != l.end(); it++)
    {
        cout << *it << " ";
    }
    cout << endl;
}

void test01()
{
    list<int>L1;
    L1.push_back(10);
    L1.push_back(20);
    L1.push_back(30);
    L1.push_back(40);
    L1.push_back(50);
    printList(L1);

    if (L1.empty())
    {
        cout << "L1为空" << endl;
    }
    else
    {
        cout << "L1不为空" << endl;
        cout << "L1元素个数:" << L1.size() << endl;
    }

    L1.resize(2);
    printList(L1);

    L1.resize(15, 10);
    printList(L1);
}

int main()
{
    test01();
    system("pause");
    return 0;
}
3.7.5 list插入和删除

作用:对数据插入和删除

函数原型

  • push_back(elem); //容器尾部插入一个元素

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

  • push_front(elem); //容器开头插入一个元素

  • pop_front(); //删除容器开头第一个元素

  • insert(pos, elem); //pos位置插入elem元素的拷贝,返回新数据的位置

  • insert(pos, n , elem); //pos位置插入n个elem数据的拷贝,无返回值

  • clear(); //清空

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

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

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

3.7.6 list数据存取

作用:数据进行存取

函数原型

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

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

3.7.7 list反转和排序

作用:容器中的元素反转,将容器中的数据进行排序

函数原型

  • reverse(); //反转链表

  • sort(); //链表排序

3.7.8 排序案例
3.8 set / multiset容器
3.8.1 set基本概念

概述:所有元素插入时自动被排序

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

set与multiset区别

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

  • multiset允许容器中有重复的元素

3.8.2 set构造和赋值

作用:创建set容器和赋值操作

构造 - 函数原型

set<T> st;         //默认构造函数
  • set(const set &st); //拷贝构造函数

赋值 - 函数原型

  • set& operator=(const set & st); //重载等号操作符
#include <iostream>
using namespace std;
#include <set>

void printSet(set<int>& s) 
{
    for (set<int>::iterator it = s.begin(); it != s.end(); it++)
    {
        cout << *it << " ";
    }
    cout << endl;
}

void test01()
{
    set<int>s1;
    s1.insert(10);
    s1.insert(20);
    s1.insert(30);
    s1.insert(40);
    s1.insert(50);
    printSet(s1);

    set<int>s2(s1);
    printSet(s2);

    set<int>s3;
    s3 = s1;
    printSet(s3);
}

int main()
{
    test01();
    system("pause");
    return 0;
}
3.8.3 set大小和交换

作用:统计大小和交换容器

函数原型

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

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

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

#include <iostream>
using namespace std;
#include <set>

void printSet(set<int>& s)
{
    for (set<int>::iterator it = s.begin(); it != s.end(); it++)
    {
        cout << *it << " ";
    }
    cout << endl;
}

void test01()
{
    set<int>s1;
    s1.insert(10);
    s1.insert(20);
    s1.insert(30);

    set<int>s2;
    s2.insert(40);
    s2.insert(50);
    s2.insert(60);

    if (s1.empty())
    {
        cout << "s1为空" << endl;
    }
    else
    {
        cout << "s1不为空" << endl;
        cout << "s1的大小为" << s1.size() << endl;
    }

    cout << "swap - before" << endl;
    printSet(s1);
    printSet(s2);

    cout << "swap - after" << endl;
    s1.swap(s2);
    printSet(s1);
    printSet(s2);
}

int main()
{
    test01();
    system("pause");
    return 0;
}
3.8.4 set插入和删除

作用:对数据进行插入和删除

函数原型

  • insert(elem); //容器中插入元素

  • clear(); //清空

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

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

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

#include <iostream>
using namespace std;
#include <set>

void printSet(set<int>& s)
{
    for (set<int>::iterator it = s.begin(); it != s.end(); it++)
    {
        cout << *it << " ";
    }
    cout << endl;
}

void test01()
{
    set<int>s1;

    s1.insert(10);
    s1.insert(20);
    s1.insert(30);

    printSet(s1);

    s1.erase(s1.begin());
    printSet(s1);

    s1.erase(20);
    printSet(s1);

    s1.erase(s1.begin(), s1.end());
    s1.clear();
    printSet(s1);
}

int main()
{
    test01();
    system("pause");
    return 0;
}
3.8.5 set查找和统计

作用:查找数据和统计数据

函数原型

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

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

#include <iostream>
using namespace std;
#include <set>

void test01()
{
    set<int>s1;

    s1.insert(10);
    s1.insert(20);
    s1.insert(30);
    s1.insert(40);
    s1.insert(50);

    set<int>::iterator pos = s1.find(20);
    if (pos != s1.end())
    {
        cout << "找到元素" << *pos << endl;
    }
    else
    {
        cout << "未找到元素" << endl;
    }

    int num = s1.count(10); 
    cout << "num = " << num << endl;
}

int main()
{
    test01();
    system("pause");
    return 0;
}
3.8.6 set和multiset区别
  • set不可插入重复数据,multiset可以

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

  • multiset不检测数据,可插入重复数据

3.8.7 pair对组创建

作用:可以返回两个数据

两种创建方式 - 函数原型:

pair<type, type> p (value1, value2);
pair<type, type> p = make_pair(value1, value2);
#include <iostream>
using namespace std;

void test01()
{
    pair<string, int>p1("小明", 19);
    cout << "姓名:" << p1.first << " 年龄: " << p1.second << endl;

    pair<string, int>p2 = make_pair("小红", 18);
    cout << "姓名:" << p2.first << " 年龄: " << p2.second << endl;
}

int main()
{
    test01();
    system("pause");
    return 0;
}
3.8.8 set容器排序

默认排序规则从小到大

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

  • 内置数据类型
#include <iostream>
using namespace std;
#include <set>

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

void test01()
{
    set<int, myCompare>s1;
    s1.insert(10);
    s1.insert(50);
    s1.insert(40);
    s1.insert(20);
    s1.insert(30);

    for (set<int, myCompare>::iterator it = s1.begin(); it != s1.end(); it++)
    {
        cout << *it << " ";
    }
    cout << endl;
}

int main()
{
    test01();
    system("pause");
    return 0;
}
  • 自定义数据类型
#include <iostream>
using namespace std;
#include <set>
#include <string>

class Student
{
public:
    Student(string name, int age)
    {
        this->m_Name = name;
        this->m_Age = age;
    }
    string m_Name;
    int m_Age;
};

class myCompare
{
public:
    bool operator()(const Student& s1, const Student &s2)const
    {
        return s1.m_Age > s2.m_Age;
    }
};

void test01()
{
    Student s1("小明", 18);
    Student s2("小红", 20);
    Student s3("小王", 19);

    set<Student, myCompare>s;
    s.insert(s1);
    s.insert(s2);
    s.insert(s3);

    for (set<Student, myCompare>::iterator it = s.begin(); it != s.end(); it++)
    {
        cout << "姓名:" << it->m_Name << " 年龄:" << it->m_Age << endl;
    }
    cout << endl;
}

int main()
{
    test01();
    system("pause");
    return 0;
}
3.9 map / multimap容器
3.9.1 map基本概念

概述

map中所有元素都是pair

pair中第一个元素为key,起索引作用,第二个元素为value

所有元素会根据元素的key自动排序

本质:map/multimap属于关联式容器,底层结构用二叉树实现的

优点:可根据key快速找到value值

map与multimap区别

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

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

3.9.2 map构造和赋值

作用:构造map容器和赋值操作

构造 - 函数原型:

map<T1, T2> mp;         //默认构造函数
  • map(const map &mp); //拷贝构造函数

赋值 - 函数原型:

  • map& operator=(const map &mp); //重载等号操作符
#include <iostream>
using namespace std;
#include <map>

void printMap(map<int, int>& m)
{
    for (map<int, int>::iterator it = m.begin(); it != m.end(); it++)
    {
        cout << "key = " << it->first << " value = " << it->second << endl;
    }
}

void test01()
{
    map<int, int>m1;
    m1.insert(pair<int, int>(1, 10));
    m1.insert(pair<int, int>(2, 20));
    m1.insert(pair<int, int>(3, 30));
    m1.insert(pair<int, int>(4, 40));
    m1.insert(pair<int, int>(5, 50));
    printMap(m1);

    map<int, int>m2(m1);
    printMap(m2);

    map<int, int>m3;
    m3 = m1;
    printMap(m3);
}

int main()
{
    test01();
    system("pause");
    return 0;
}
3.9.3 map大小和交换

作用:统计map容器大小和map容器交换

函数原型

  • size(); //判断容器中元素个数

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

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

#include <iostream>
using namespace std;
#include <map>

void printMap(map<int, int>& m)
{
    for (map<int, int>::iterator it = m.begin(); it != m.end(); it++)
    {
        cout << "key = " << it->first << " value = " << it->second << endl;
    }
}

void test01()
{
    map<int, int>m1;
    m1.insert(pair<int, int>(1, 10));
    m1.insert(pair<int, int>(2, 20));
    m1.insert(pair<int, int>(3, 30));

    map<int, int>m2;
    m2.insert(pair<int, int>(4, 40));
    m2.insert(pair<int, int>(5, 50));
    m2.insert(pair<int, int>(6, 60));

    if (m1.empty())
    {
        cout << "m1为空" << endl;
    }
    else
    {
        cout << "m1不为空" << endl;
        cout << "m1的大小为" << m1.size() << endl;
    }

    cout << "swap - before " << endl;
    printMap(m1);
    printMap(m2);

    cout << "swap - after " << endl;
    m1.swap(m2);
    printMap(m1);
    printMap(m2);
}

int main()
{
    test01();
    system("pause");
    return 0;
}
3.9.4 map插入和删除

作用:对数据进行插入和删除

函数原型

  • insert(elem); //容器中插入元素

  • clear(); //清空

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

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

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

#include <iostream>
using namespace std;
#include <map>

void printMap(map<int, int>& m)
{
    for (map<int, int>::iterator it = m.begin(); it != m.end(); it++)
    {
        cout << "key = " << it->first << " value = " << it->second << endl;
    }
}

void test01()
{
    map<int, int>m1;
    //插入 - 方法1
    m1.insert(pair<int, int>(1, 10));
    //插入 - 方法2
    m1.insert(make_pair(2, 20));
    //插入 - 方法3
    m1.insert(map<int, int>::value_type(3, 30));
    //插入 - 方法4
    m1[4] = 40;
    printMap(m1);

    //删除
    m1.erase(m1.begin());
    printMap(m1);

    m1.erase(3);
    printMap(m1);

    m1.erase(m1.begin(),m1.end());
    m1.clear();
    printMap(m1);
}

int main()
{
    test01();
    system("pause");
    return 0;
}
3.9.5 map查找和统计

作用:对数据进行查找和统计

函数原型

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

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

#include <iostream>
using namespace std;
#include <map>

void printMap(map<int, int>& m)
{
    for (map<int, int>::iterator it = m.begin(); it != m.end(); it++)
    {
        cout << "key = " << it->first << " value = " << it->second << endl;
    }
}

void test01()
{
    map<int, int>m1;

    m1.insert(pair<int, int>(1, 10));
    m1.insert(pair<int, int>(2, 20));
    m1.insert(pair<int, int>(3, 30));
    m1.insert(pair<int, int>(4, 40));

    map<int, int>::iterator pos = m1.find(2);

    if (pos != m1.end())
    {
        cout << "查到元素 key = " << pos->first << " value = " << pos->second << endl;
    }
    else
    {
        cout << "未找到元素" << endl;
    }

    //map不允许插入重复key元素,结果要么0 要么1
    int num = m1.count(1);
    cout << "num = " << num << endl;
}

int main()
{
    test01();
    system("pause");
    return 0;
}
3.9.6 map容器排序

默认规则按照key值从小到大排序

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

#include <iostream>
using namespace std;
#include <map>

class myCompare
{
public:
    bool operator()( int val1,  int val2)const
    {
        //降序
        return val1 > val2;
    }
};

void test01()
{
    map<int, int, myCompare>m1;

    m1.insert(make_pair(1, 10));
    m1.insert(make_pair(4, 40));
    m1.insert(make_pair(3, 30));
    m1.insert(make_pair(2, 20));

    for (map<int, int, myCompare>::iterator it = m1.begin(); it != m1.end(); it++)
    {
        cout << "key = " << it->first << " value = " << it->second << endl;
    }
}

int main()
{
    test01();
    system("pause");
    return 0;
}
3.10 案例 - 待更新

C++进阶编程 — 4.STL函数对象

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值