C++容器map及unordered_map底层实现和性能上有所不同

std::map 和 std::unordered_map都是 C++ 标准库中用于实现关联容器的类模板,但它们在底层实现和性能上有所不同。

1. std::map:

  • 使用红黑树实现,保持元素的有序性。因此,所有操作的时间复杂度都是 O(log n),其中 n 是元素个数。

  • 元素按键排序存储,键是唯一的,每个键最多只能出现一次。

  • 适用于需要有序存储键值对的情况,例如需要按照键的顺序进行遍历或查找的场景。

当需要按照键的顺序进行存储和访问时,可以使用 std::map。例如,存储学生的分数,并按照学生姓名的字典顺序进行排序:

cpp 复制代码
#include <iostream>
#include <map>
#include <string>

int main() {
    std::map<std::string, int> studentScores;

    // 添加学生分数
    studentScores["Alice"] = 95;
    studentScores["Bob"] = 87;
    studentScores["Charlie"] = 92;

    // 遍历输出学生分数(按姓名字典顺序)
    for (const auto& pair : studentScores) {
        std::cout << pair.first << ": " << pair.second << std::endl;
    }

    return 0;
}

2. std::unordered_map:

  • 使用哈希表实现,插入、查找、删除操作的平均时间复杂度为 O(1),但最坏情况下可能会达到 O(n)。

  • 元素存储时没有顺序限制,但键必须是唯一的。

  • 适用于对插入和查找性能有较高要求,并且不要求元素有序存储的情况。

因此,选择 std::map 还是 std::unordered_map 取决于具体的需求。如果需要有序存储或者操作少量数据,可以选择 std::map;如果对性能要求较高,并且不需要有序存储,可以选择 std::unordered_map。

cpp 复制代码
#include <iostream>
#include <unordered_map>
#include <string>

int main() {
    std::unordered_map<std::string, int> studentScores;

    // 添加学生分数
    studentScores["S001"] = 95;
    studentScores["S002"] = 87;
    studentScores["S003"] = 92;

    // 查找学生分数
    std::string studentID = "S002";
    if (studentScores.find(studentID) != studentScores.end()) {
        std::cout << "Score of student " << studentID << ": " << studentScores[studentID] << std::endl;
    } else {
        std::cout << "Student " << studentID << " not found." << std::endl;
    }

    return 0;
}

**`std::unordered_map` 提供了一系列方法来进行元素的插入、查找、删除等操作。**以下是一些常用的方法:

  1. **插入元素**:
  • `insert`: 将键值对插入到 `std::unordered_map` 中。
  1. **访问元素**:
  • `operator[]`: 通过键来访问元素的值。

  • `at`: 通过键来访问元素的值,类似于 `operator[]`,但提供了边界检查。

  1. **查找元素**:
  • `find`: 查找给定键的元素,返回指向该元素的迭代器,如果未找到,则返回 `std::unordered_map::end()`。

  • `count`: 返回指定键的元素个数,由于每个键在 `std::unordered_map` 中最多出现一次,因此结果为 0 或 1。

  1. **删除元素**:
  • `erase`: 删除指定键的元素或一定范围内的元素。

  • `clear`: 清空 `std::unordered_map` 中的所有元素。

  1. **容量相关**:
  • `empty`: 检查 `std::unordered_map` 是否为空。

  • `size`: 返回 `std::unordered_map` 中元素的数量。

  1. **哈希策略**:
  • `hash_function`: 返回哈希函数对象,用于计算键的哈希值。

  • `key_eq`: 返回用于比较键是否相等的函数对象。

这些方法使得在 `std::unordered_map` 中进行元素的操作变得非常方便。


**`std::map` 提供了一系列方法来进行元素的插入、查找、删除等操作。**以下是一些常用的方法:

  1. **插入元素**:
  • `insert`: 将键值对插入到 `std::map` 中。
  1. **访问元素**:
  • `operator[]`: 通过键来访问元素的值。

  • `at`: 通过键来访问元素的值,类似于 `operator[]`,但提供了边界检查。

  1. **查找元素**:
  • `find`: 查找给定键的元素,返回指向该元素的迭代器,如果未找到,则返回 `std::map::end()`。

  • `count`: 返回指定键的元素个数,由于每个键在 `std::map` 中最多出现一次,因此结果为 0 或 1。

  1. **删除元素**:
  • `erase`: 删除指定键的元素或一定范围内的元素。

  • `clear`: 清空 `std::map` 中的所有元素。

  1. **容量相关**:
  • `empty`: 检查 `std::map` 是否为空。

  • `size`: 返回 `std::map` 中元素的数量。

  1. **迭代器**:
  • `begin`: 返回指向第一个元素的迭代器。
  • `end`: 返回指向最后一个元素之后位置的迭代器。
  1. **比较操作**:
  • `key_comp`: 返回用于比较键的函数对象。

  • `value_comp`: 返回用于比较值的函数对象。

这些方法使得在 `std::map` 中进行元素的操作变得非常方便。

相关推荐
ByteCraze10 小时前
秋招被问到的常见问题
开发语言·javascript·原型模式
码银11 小时前
【python】基于 生活方式与健康数据预测数据集(Lifestyle and Health Risk Prediction)的可视化练习,附数据集源文件。
开发语言·python·生活
Pluchon11 小时前
硅基计划5.0 MySQL 叁 E-R关系图&联合/多表查询&三大连接&子查询&合并查询
开发语言·数据库·学习·mysql
kyle~11 小时前
C++---嵌套类型(Nested Types)封装与泛型的基石
开发语言·c++·算法
sali-tec11 小时前
C# 基于halcon的视觉工作流-章48-短路断路
开发语言·图像处理·人工智能·算法·计算机视觉
无敌最俊朗@11 小时前
解决 QML 中使用 Qt Charts 崩溃的三个关键步骤
开发语言·qt
会飞的小新12 小时前
C 标准库之 <errno.h> 详解与深度解析
c语言·开发语言
胡八一12 小时前
30 分钟上手 exp4j:在 Java 中安全、灵活地计算数学表达式
java·开发语言·安全
郝学胜-神的一滴13 小时前
Linux 进程控制块(PCB)解析:深入理解进程管理机制
linux·服务器·开发语言
后端小张13 小时前
【鸿蒙开发手册】重生之我要学习鸿蒙HarmonyOS开发
开发语言·学习·华为·架构·harmonyos·鸿蒙·鸿蒙系统