C++进阶之一篇文章教会你什么是map和set(下)

简介: 6.set观察器和操作成员函数Observerskey_comp(返回键的比较对象):key_compare key_comp() const;

6.set观察器和操作成员函数

Observers

  1. key_comp(返回键的比较对象):
  • key_compare key_comp() const;
  • 返回一个键的比较对象,用于比较容器中键的大小关系。
  1. value_comp(返回值的比较对象):
  • value_compare value_comp() const;
  • 返回一个值的比较对象,用于比较容器中的值的大小关系。

Operations

  1. find(查找元素):
  • iterator find(const key_type& key);
  • 返回一个迭代器,指向键等于给定键的元素。如果未找到元素,则返回指向容器末尾的迭代器 end()
  1. count(计算特定值的元素个数):
  • size_type count(const key_type& key);
  • 返回具有指定值的元素个数。通常情况下,由于键是唯一的,结果将是0或1。
  1. lower_bound(返回下限迭代器):
  • iterator lower_bound(const key_type& key);
  • 返回一个迭代器,指向第一个大于或等于给定键的元素位置。
  1. upper_bound(返回上限迭代器):
  • iterator upper_bound(const key_type& key);
  • 返回一个迭代器,指向第一个大于给定键的元素位置。
  1. equal_range(获取相等元素的范围):
  • pair<iterator, iterator> equal_range(const key_type& key);
  • 返回一个包含两个迭代器的pair,第一个迭代器指向第一个等于给定键的元素,第二个迭代器指向第一个大于给定键的元素。

示例

#include <iostream>
#include <set>
int main() {
    std::set<int> mySet = {1, 2, 3, 4, 5};
    // 使用 key_comp 获取键的比较对象
    std::set<int>::key_compare keyComp = mySet.key_comp();
    // 使用 value_comp 获取值的比较对象
    std::set<int>::value_compare valueComp = mySet.value_comp();
    // 查找元素
    std::set<int>::iterator it = mySet.find(3);
    if (it != mySet.end()) {
        std::cout << "找到元素 3" << std::endl;
    } else {
        std::cout << "未找到元素 3" << std::endl;
    }
    // 计算特定值的元素个数
    size_t count = mySet.count(4);
    std::cout << "值为 4 的元素个数: " << count << std::endl;
    // 获取下限迭代器
    std::set<int>::iterator lower = mySet.lower_bound(2);
    std::cout << "下限迭代器指向大于或等于 2 的元素位置: " << *lower << std::endl;
    // 获取上限迭代器
    std::set<int>::iterator upper = mySet.upper_bound(4);
    std::cout << "上限迭代器指向大于 4 的元素位置: " << *upper << std::endl;
    // 获取相等元素的范围
    std::pair<std::set<int>::iterator, std::set<int>::iterator> range = mySet.equal_range(3);
    std::cout << "相等元素范围: [" << *(range.first) << ", " << *(range.second) << "]" << std::endl;
    return 0;
}

7.set应用场景

#include <set>
void TestSet()
{
    // 用数组array中的元素构造set
    int array[] = { 1, 3, 5, 7, 9, 2, 4, 6, 8, 0, 1, 3, 5, 7, 9, 2, 4,6, 8, 0 };
    set<int> s(array, array+sizeof(array)/sizeof(array));
    cout << s.size() << endl;
    // 正向打印set中的元素,从打印结果中可以看出:set可去重
    for (auto& e : s)
    cout << e << " ";
    cout << endl;
    // 使用迭代器逆向打印set中的元素
    for (auto it = s.rbegin(); it != s.rend(); ++it)
    cout << *it << " ";
    cout << endl;
    // set中值为3的元素出现了几次
    cout << s.count(3) << endl;
}

set和multiset的区别

std::setstd::multiset 都是 C++ 标准库中的关联式容器,它们用于存储一组元素,且元素是按照一定的顺序排列的。然而,它们之间有一个关键的区别:

  1. 唯一性:
  • std::setstd::set 中的元素是唯一的,不允许重复的元素存在。如果试图插入重复的元素,新元素将不会被插入。
  • std::multisetstd::multiset 允许存储重复的元素,可以插入多个具有相同键值的元素。

下面是更详细的比较:

  • std::set
  • 元素是唯一的,不允许重复。
  • 插入操作会检查元素是否已存在,如果已存在则插入不成功。
  • 查找操作在 O(log n) 的时间内完成,因为元素唯一。
  • 适用于需要维护一组唯一值的情况,例如去重操作。
  • std::multiset
  • 允许存储重复的元素,不会检查重复性。
  • 插入操作总是成功,允许存储多个相同键值的元素。
  • 查找操作在 O(log n) 的时间内完成,因为仍然具有排序特性。
  • 适用于需要允许重复值的情况,例如统计元素出现次数。
  • multiset在底层实际存储的是<int, int>的键值对。

在选择使用 std::set 还是 std::multiset 时,取决于你的数据需求。如果需要维护一组唯一的值,使用 std::set;如果允许重复值,并且需要统计重复值的出现次数,使用 std::multiset

map

1.map模板参数列表

template < class Key,                                     // map::key_type
           class T,                                       // map::mapped_type
           class Compare = less<Key>,                     // map::key_compare
           class Alloc = allocator<pair<const Key,T> >    // map::allocator_type
           > class map;

std::map是一个关联式容器,它提供了key-value对的存储和管理。以下是代码中各个模板参数的解释:

  • Key:表示std::map容器中的键类型,也就是键值对中的键的类型。
  • T:表示std::map容器中的值类型,也就是键值对中的值的类型。
  • Compare:表示比较键的方式的函数对象,默认使用 std::less<Key>,可以根据需要自定义键的比较方式。
  • Alloc:表示用于分配内存的分配器类型,默认使用 std::allocator<std::pair<const Key, T>>,通常情况下不需要自定义。

通过这个模板声明,你可以创建不同类型的std::map容器,以存储不同类型的key-value对。例如,如果要创建一个存储整数键和字符串值的std::map容器,可以这样使用:

std::map<int, std::string> myMap;

这将创建一个std::map容器,其中键的类型是整数 (int),值的类型是字符串 (std::string)。您可以使用该容器来存储和检索整数和字符串之间的映射关系。

成员类型

2.map的构造

  1. empty(默认构造函数):
  • explicit map(const key_compare& comp = key_compare(), const allocator_type& alloc = allocator_type());
  • 这是std::map的默认构造函数,它创建一个空的std::map对象。
  • comp 参数是可选的,表示用于比较键的自定义比较函数,默认使用 key_compare(),即使用std::less<Key>
  • alloc 参数是可选的,表示用于内存分配的自定义分配器,默认使用 allocator_type(),即使用std::allocator<std::pair<const Key, T>>
  1. range(范围构造函数):
  • template <class InputIterator> map(InputIterator first, InputIterator last, const key_compare& comp = key_compare(), const allocator_type& alloc = allocator_type());
  • 这个构造函数允许您从一个范围(由迭代器 firstlast 定义)初始化std::map容器。
  • comp 参数是可选的,表示用于比较键的自定义比较函数,默认使用 key_compare()
  • alloc 参数是可选的,表示用于内存分配的自定义分配器,默认使用 allocator_type()
  1. copy(复制构造函数):
  • map(const map& x);
  • 这个构造函数用于创建一个新的std::map容器,并以另一个std::map容器 x 的内容进行初始化,即复制x中的键值对到新的容器中。

示例

#include <iostream>
#include <map>
int main() {
    // 使用默认构造函数创建一个空的 std::map
    std::map<int, std::string> myMap1;
    // 使用范围构造函数创建并初始化 std::map
    std::map<int, std::string> myMap2 = {{1, "One"}, {2, "Two"}, {3, "Three"}};
    // 使用复制构造函数创建一个与 myMap2 相同内容的副本
    std::map<int, std::string> myMap3(myMap2);
    // 输出容器内容
    std::cout << "myMap1: " << myMap1.size() << " elements" << std::endl;
    std::cout << "myMap2: " << myMap2.size() << " elements" << std::endl;
    std::cout << "myMap3: " << myMap3.size() << " elements" << std::endl;
    return 0;
}

在此示例中,我们演示了三种不同的std::map构造函数的使用方式,包括默认构造函数、范围构造函数和复制构造函数。根据构造函数的不同用途,可以创建空容器、初始化容器或复制另一个容器的内容。

赋值运算符重载

将一个 std::map 的内容复制到另一个已存在的 std::map 中。例如:

std::map<int, std::string> sourceMap = {{1, "One"}, {2, "Two"}};
std::map<int, std::string> targetMap;
targetMap = sourceMap; // 使用拷贝赋值运算符将内容复制到目标容器

它会创建一个新的 std::map 容器,其中包含与原始容器相同的键值对。这是一种将数据从一个容器复制到另一个容器的常见方式。

3.map迭代器

std::map容器提供了多种迭代器,用于访问容器中的元素。以下是这些迭代器的详细描述:

  1. begin
  • iterator begin();
  • 返回一个迭代器,指向std::map容器中第一个元素的位置。
  1. end
  • iterator end();
  • 返回一个迭代器,指向std::map容器中的末尾(尾后位置)。
  1. rbegin
  • reverse_iterator rbegin();
  • 返回一个逆向迭代器,指向std::map容器中的最后一个元素的位置。
  1. rend
  • reverse_iterator rend();
  • 返回一个逆向迭代器,指向std::map容器中的逆向末尾(逆向尾后位置)。
  1. cbegin
  • const_iterator cbegin() const;
  • 返回一个常量迭代器,指向std::map容器中第一个元素的位置。用于只读访问。
  1. cend
  • const_iterator cend() const;
  • 返回一个常量迭代器,指向std::map容器中的末尾(尾后位置)。用于只读访问。
  1. crbegin
  • const_reverse_iterator crbegin() const;
  • 返回一个常量逆向迭代器,指向std::map容器中的最后一个元素的位置。用于只读访问。
  1. crend
  • const_reverse_iterator crend() const;
  • 返回一个常量逆向迭代器,指向std::map容器中的逆向末尾(逆向尾后位置)。用于只读访问。

示例

#include <iostream>
#include <map>
int main() {
    // 创建一个 std::map 容器并初始化
    std::map<int, std::string> myMap = {{1, "One"}, {2, "Two"}, {3, "Three"}};
    // 使用正向迭代器遍历容器
    std::cout << "正向迭代器遍历容器:" << std::endl;
    for (std::map<int, std::string>::iterator it = myMap.begin(); it != myMap.end(); ++it) {
        std::cout << "键: " << it->first << ", 值: " << it->second << std::endl;
    }
    // 使用逆向迭代器遍历容器
    std::cout << "逆向迭代器遍历容器:" << std::endl;
    for (std::map<int, std::string>::reverse_iterator rit = myMap.rbegin(); rit != myMap.rend(); ++rit) {
        std::cout << "键: " << rit->first << ", 值: " << rit->second << std::endl;
    }
    // 使用常量迭代器遍历容器(只读访问)
    std::cout << "常量迭代器遍历容器:" << std::endl;
    for (std::map<int, std::string>::const_iterator cit = myMap.cbegin(); cit != myMap.cend(); ++cit) {
        std::cout << "键: " << cit->first << ", 值: " << cit->second << std::endl;
    }
    // 使用常量逆向迭代器遍历容器(只读访问)
    std::cout << "常量逆向迭代器遍历容器:" << std::endl;
    for (std::map<int, std::string>::const_reverse_iterator crit = myMap.crbegin(); crit != myMap.crend(); ++crit) {
        std::cout << "键: " << crit->first << ", 值: " << crit->second << std::endl;
    }
    return 0;
}

这个示例演示了如何使用不同类型的迭代器遍历std::map容器中的元素:

  • 使用正向迭代器 begin()end() 遍历容器。
  • 使用逆向迭代器 rbegin()rend() 逆向遍历容器。
  • 使用常量迭代器 cbegin()cend() 以只读方式遍历容器。
  • 使用常量逆向迭代器 crbegin()crend() 以只读方式逆向遍历容器。

4.map容量和元素访问函数

这些是关于std::map容器的一些容量和元素访问相关的成员函数:

  1. empty(检查是否为空):
  • bool empty() const;
  • 用于检查std::map容器是否为空。如果容器为空,返回true;否则返回false
  1. size(返回容器大小):
  • size_type size() const;
  • 返回std::map容器中键值对的数量,也就是容器的大小。
  1. max_size(返回最大容量):
  • size_type max_size() const;
  • 返回std::map容器可以容纳的最大元素数量。这通常受到系统内存限制的影响。
  1. operator[](访问元素):
  • T& operator[](const key_type& key);
  • 允许通过键访问容器中的元素。如果键存在,则返回相应的值的引用,如果不存在,则会插入一个具有该键的默认值,并返回引用。请注意,如果键不存在,将插入一个具有默认值的键值对。
  1. at(访问元素):
  • T& at(const key_type& key);
  • 允许通过键访问容器中的元素,类似于 operator[]。但与 operator[] 不同,如果键不存在,at 会抛出 std::out_of_range 异常。

示例

#include <iostream>
#include <map>
int main() {
    std::map<int, std::string> myMap = {{1, "One"}, {2, "Two"}, {3, "Three"}};
    // 检查容器是否为空
    if (myMap.empty()) {
        std::cout << "容器为空" << std::endl;
    } else {
        std::cout << "容器不为空" << std::endl;
    }
    // 获取容器的大小
    std::cout << "容器大小为: " << myMap.size() << std::endl;
    // 访问容器中的元素
    std::string value = myMap[2]; // 使用 operator[]
    std::cout << "键 2 对应的值为: " << value << std::endl;
    try {
        std::string value = myMap.at(4); // 键 4 不存在,会抛出异常
    } catch (const std::out_of_range& e) {
        std::cerr << "键 4 不存在: " << e.what() << std::endl;
    }
    return 0;
}

在此示例中,我们演示了如何使用std::map容器的容量和元素访问成员函数,包括检查容器是否为空、获取容器大小、通过键访问元素以及处理键不存在的情况。

5.map修改器函数

  1. insert(插入元素):
  • pair<iterator, bool> insert(const value_type& value);
  • 用于插入键值对(键值对的类型为 value_type)到std::map容器中。如果插入成功,返回一个迭代器指向插入的元素和 true;如果元素已存在,则返回一个迭代器指向现有元素和 false
  1. erase(删除元素):
  • iterator erase(iterator position);
  • size_type erase(const key_type& key);
  • 用于删除容器中的元素。第一种形式删除由迭代器 position 指定的元素,并返回指向下一个元素的迭代器。第二种形式删除指定键的元素,并返回删除的元素数量。
  1. swap(交换内容):
  • void swap(map& x);
  • 用于交换两个std::map容器的内容,即交换键值对。交换后,两个容器的内容完全交换。
  1. clear(清空内容):
  • void clear();
  • 用于清空std::map容器中的所有元素,使容器成为空容器。
  1. emplace(构造并插入元素):
  • pair<iterator, bool> emplace(Args&&... args);
  • 允许构造并插入元素,其中 Args 是键值对的构造参数。如果插入成功,返回一个迭代器指向插入的元素和 true;如果元素已存在,则返回一个迭代器指向现有元素和 false
  1. emplace_hint(构造并插入元素带提示):
  • iterator emplace_hint(const_iterator position, Args&&... args);
  • 允许构造并插入元素,其中 Args 是键值对的构造参数,并且可以提供插入位置的提示。返回一个迭代器指向插入的元素。

示例

#include <iostream>
#include <map>
int main() {
    std::map<int, std::string> myMap;
    // 插入元素
    myMap.insert(std::make_pair(1, "One"));
    myMap.insert(std::make_pair(2, "Two"));
    // 删除元素
    myMap.erase(2);
    // 交换容器内容
    std::map<int, std::string> anotherMap = {{3, "Three"}, {4, "Four"}};
    myMap.swap(anotherMap);
    // 清空容器
    myMap.clear();
    // 构造并插入元素
    myMap.emplace(5, "Five");
    // 使用 emplace_hint 插入元素
    std::map<int, std::string>::iterator it = myMap.emplace_hint(myMap.begin(), 6, "Six");
    // 输出容器内容
    for (const auto& pair : myMap) {
        std::cout << "键: " << pair.first << ", 值: " << pair.second << std::endl;
    }
    return 0;
}

在此示例中,我们演示了如何使用std::map容器的修改器成员函数,包括插入、删除、交换和清空元素,以及使用 emplaceemplace_hint 插入元素的方式。

6.map观察器和操作成员函数

Observers

  1. key_comp(返回键的比较对象):
  • key_compare key_comp() const;
  • 返回一个键的比较对象,用于比较容器中键的大小关系。
  1. value_comp(返回值的比较对象):
  • value_compare value_comp() const;
  • 返回一个值的比较对象,用于比较容器中的值的大小关系。

Operations

  1. find(查找元素):
  • iterator find(const key_type& key);
  • 返回一个迭代器,指向键等于给定键的元素。如果未找到元素,则返回指向容器末尾的迭代器 end()
  1. count(计算特定键的元素个数):
  • size_type count(const key_type& key);
  • 返回具有指定键的元素个数。通常情况下,由于键是唯一的,结果将是0或1。
  1. lower_bound(返回下限迭代器):
  • iterator lower_bound(const key_type& key);
  • 返回一个迭代器,指向第一个大于或等于给定键的元素位置。
  1. upper_bound(返回上限迭代器):
  • iterator upper_bound(const key_type& key);
  • 返回一个迭代器,指向第一个大于给定键的元素位置。
  1. equal_range(获取相等元素的范围):
  • pair<iterator, iterator> equal_range(const key_type& key);
  • 返回一个包含两个迭代器的pair,第一个迭代器指向第一个等于给定键的元素,第二个迭代器指向第一个大于给定键的元素。

以下是示例用法

#include <iostream>
#include <map>
int main() {
    std::map<int, std::string> myMap = {{1, "One"}, {2, "Two"}, {3, "Three"}};
    // 使用 find 查找元素
    std::map<int, std::string>::iterator it = myMap.find(2);
    if (it != myMap.end()) {
        std::cout << "找到键 2,值为: " << it->second << std::endl;
    } else {
        std::cout << "未找到键 2" << std::endl;
    }
    // 使用 count 计算特定键的元素个数
    size_t count = myMap.count(3);
    std::cout << "键 3 的元素个数: " << count << std::endl;
    // 使用 lower_bound 获取下限迭代器
    std::map<int, std::string>::iterator lower = myMap.lower_bound(2);
    std::cout << "下限迭代器指向键 2,值为: " << lower->second << std::endl;
    // 使用 upper_bound 获取上限迭代器
    std::map<int, std::string>::iterator upper = myMap.upper_bound(2);
    std::cout << "上限迭代器指向大于键 2 的元素,值为: " << upper->second << std::endl;
    // 使用 equal_range 获取相等元素的范围
    std::pair<std::map<int, std::string>::iterator, std::map<int, std::string>::iterator> range = myMap.equal_range(2);
    std::cout << "相等元素范围: [" << range.first->second << ", " << range.second->second << "]" << std::endl;
    return 0;
}

在此示例中,我们演示了如何使用std::map容器的观察器和操作成员函数,包括查找元素、计算特定键的元素个数、获取下限迭代器、获取上限迭代器以及获取相等元素的范围。这些函数使得在std::map容器中执行查找和搜索操作变得非常方便。

7.map应用场景

#include <string>
#include <map>
void TestMap()
{
  map<string, string> m;
  // 向map中插入元素的方式:
  // 将键值对<"peach","桃子">插入map中,用pair直接来构造键值对
  m.insert(pair<string, string>("peach", "桃子"));
  // 将键值对<"peach","桃子">插入map中,用make_pair函数来构造键值对
  m.insert(make_pair("banan", "香蕉"));
  // 借用operator[]向map中插入元素
  /*
  operator[]的原理是:
  用<key, T()>构造一个键值对,然后调用insert()函数将该键值对插入到map中
  如果key已经存在,插入失败,insert函数返回该key所在位置的迭代器
  如果key不存在,插入成功,insert函数返回新插入元素所在位置的迭代器
  operator[]函数最后将insert返回值键值对中的value返回
  */
  // 将<"apple", "">插入map中,插入成功,返回value的引用,将“苹果”赋值给该引用结果,
    m["apple"] = "苹果";
  // key不存在时抛异常
  //m.at("waterme") = "水蜜桃";
    cout << m.size() << endl;
    // 用迭代器去遍历map中的元素,可以得到一个按照key排序的序列
    for (auto& e : m)
      cout << e.first << "--->" << e.second << endl;
    cout << endl;
    // map中的键值对key一定是唯一的,如果key存在将插入失败
    auto ret = m.insert(make_pair("peach", "桃色"));
    if (ret.second)
      cout << "<peach, 桃色>不在map中, 已经插入" << endl;
    else
      cout << "键值为peach的元素已经存在:" << ret.first->first << "--->"
      << ret.first->second << " 插入失败" << endl;
    // 删除key为"apple"的元素
    m.erase("apple");
    if (1 == m.count("apple"))
      cout << "apple还在" << endl;
    else
      cout << "apple被吃了" << endl;
}

map和multimap的区别

std::mapstd::multimap 都是 C++ 标准库中的关联式容器,它们用于存储一组key-value对(键值对),并根据键对元素进行排序。它们之间的主要区别在于唯一性和允许重复性:

std::map

  • std::map 是一个关联容器,其中的键是唯一的,每个键只能关联一个值。
  • 如果试图插入已存在的键,新值将覆盖旧值。
  • 使用 operator[]insert 插入元素。
  • 查找操作(例如 findcountlower_boundupper_bound)返回匹配的唯一元素。

std::multimap

  • std::multimap 也是一个关联容器,允许多个具有相同键的值存在。
  • 可以插入多个具有相同键的值,不会覆盖旧值。
  • 使用 insert 插入元素。
  • 查找操作返回匹配的所有元素,因为可以有多个相同键的元素。

以下是示例用法和比较:

std::map 示例:

#include <iostream>
#include <map>
int main() {
    std::map<int, std::string> myMap;
    // 插入键值对
    myMap[1] = "One";
    myMap[2] = "Two";
    myMap[3] = "Three";
    // 重复键值对将覆盖旧值
    myMap[2] = "New Two";
    // 查找键为 2 的元素
    std::map<int, std::string>::iterator it = myMap.find(2);
    if (it != myMap.end()) {
        std::cout << "找到键 2,值为: " << it->second << std::endl;
    }
    return 0;
}

std::multimap 示例:

#include <iostream>
#include <map>
int main() {
    std::multimap<int, std::string> myMultiMap;
    // 插入多个具有相同键的值
    myMultiMap.insert(std::make_pair(1, "One"));
    myMultiMap.insert(std::make_pair(2, "Two"));
    myMultiMap.insert(std::make_pair(2, "Another Two"));
    myMultiMap.insert(std::make_pair(3, "Three"));
    // 查找键为 2 的所有元素
    auto range = myMultiMap.equal_range(2);
    for (auto it = range.first; it != range.second; ++it) {
        std::cout << "找到键 2,值为: " << it->second << std::endl;
    }
    return 0;
}

总结

  • 如果需要维护唯一key-value对,使用 std::map
  • 如果允许具有相同键的多个值存在,使用 std::multimap


相关文章
|
13天前
|
算法
你对Collection中Set、List、Map理解?
你对Collection中Set、List、Map理解?
49 18
你对Collection中Set、List、Map理解?
|
6天前
|
存储 缓存 安全
只会“有序无序”?面试官嫌弃的List、Set、Map回答!
小米,一位热衷于技术分享的程序员,通过与朋友小林的对话,详细解析了Java面试中常见的List、Set、Map三者之间的区别,不仅涵盖了它们的基本特性,还深入探讨了各自的实现原理及应用场景,帮助面试者更好地准备相关问题。
42 20
|
23天前
|
存储 C++ 容器
【C++】map、set基本用法
本文介绍了C++ STL中的`map`和`set`两种关联容器。`map`用于存储键值对,每个键唯一;而`set`存储唯一元素,不包含值。两者均基于红黑树实现,支持高效的查找、插入和删除操作。文中详细列举了它们的构造方法、迭代器、容量检查、元素修改等常用接口,并简要对比了`map`与`set`的主要差异。此外,还介绍了允许重复元素的`multiset`和`multimap`。
29 3
【C++】map、set基本用法
|
23天前
|
存储 算法 C++
【C++】unordered_map(set)
C++中的`unordered`容器(如`std::unordered_set`、`std::unordered_map`)基于哈希表实现,提供高效的查找、插入和删除操作。哈希表通过哈希函数将元素映射到特定的“桶”中,每个桶可存储一个或多个元素,以处理哈希冲突。主要组成部分包括哈希表、哈希函数、冲突处理机制、负载因子和再散列,以及迭代器。哈希函数用于计算元素的哈希值,冲突通过开链法解决,负载因子控制哈希表的扩展。迭代器支持遍历容器中的元素。`unordered_map`和`unordered_set`的插入、查找和删除操作在理想情况下时间复杂度为O(1),但在冲突较多时可能退化为O(n)。
20 5
|
23天前
|
存储 C++ 容器
【C++】map的模拟实现
C++中的`map`是STL中的一种关联容器,存储键值对且键唯一。`map`基于红黑树实现,自动按键排序,支持动态调整、复杂数据类型、丰富的成员函数及双向迭代器。插入、查找等操作保证了对数时间复杂度,适用于需要快速查找和有序存储的场景。
21 3
|
23天前
|
存储 C++ 容器
【C++】set模拟实现
C++中的`set`是STL提供的一种关联容器,用于存储唯一元素并自动按特定顺序(默认升序)排序。其内部通过红黑树实现,保证了高效的插入、删除和查找操作,时间复杂度均为O(log n)。`set`支持迭代器遍历,提供了良好的数据访问接口。
29 3
|
2月前
|
存储 JavaScript 前端开发
Set、Map、WeakSet 和 WeakMap 的区别
在 JavaScript 中,Set 和 Map 用于存储唯一值和键值对,支持多种操作方法,如添加、删除和检查元素。WeakSet 和 WeakMap 则存储弱引用的对象,有助于防止内存泄漏,适合特定场景使用。
|
3月前
|
存储 Java API
【数据结构】map&set详解
本文详细介绍了Java集合框架中的Set系列和Map系列集合。Set系列包括HashSet(哈希表实现,无序且元素唯一)、LinkedHashSet(保持插入顺序的HashSet)、TreeSet(红黑树实现,自动排序)。Map系列为双列集合,键值一一对应,键不可重复,值可重复。文章还介绍了HashMap、LinkedHashMap、TreeMap的具体实现与应用场景,并提供了面试题示例,如随机链表复制、宝石与石头、前K个高频单词等问题的解决方案。
44 6
【数据结构】map&set详解
|
2月前
|
存储 缓存 Java
【用Java学习数据结构系列】HashMap与TreeMap的区别,以及Map与Set的关系
【用Java学习数据结构系列】HashMap与TreeMap的区别,以及Map与Set的关系
41 1
|
3月前
|
算法
你对Collection中Set、List、Map理解?
你对Collection中Set、List、Map理解?
40 5