map和set

文章目录

  • 1. 关联式容器
  • 2. 键值对 (KV模型)
  • 3. 树形结构的关联式容器
    • 3.1 set
    • 3.2 map
    • 3.3 multiset 和multimap
  • 4. OJ练习

1. 关联式容器

像我们所了解的STL中的部分容器,比如:vector、list、dequeue、forward_list(c++11)等这些容器统称为序列式容器,因为其底层为线性序列的数据结构,里面存储的是元素本身。那么什么又是关联式容器呢??两者之间又有什么区别呢??

关联式容器也是用来存储数据的, 和序列性容器不一样的是,关联式容器是非线性的树结构,更准确的说是二叉树结构。各元素之间没有严格的物理上的顺序关系,也就是说元素在容器中并没有保存元素置入容器时的逻辑顺序。但是关联式容器提供了另一种根据元素特点排序的功能,这样迭代器就能根据元素的特点“顺序地”获取元素。关联式容器另一个显著的特点是它是以键值的方式来保存数据,就是说它能把关键字和值关联起来保存,而顺序性容器只能保存一种(可以认为它只保存关键字,也可以认为它只保存值)。其里面存储的是结构的键值对,在数据检索时比序列式容器效率更高。

2. 键值对 (KV模型)

用来表示具有一一对应关系的一种结构,该结构中一般只包含两个成员变量key和value,key代表键值,value表示与key对应的信息。

例:生活中的KV模型,比如英汉字典,在字典中每个单词都有其对一个的含义,我们可以通过单词找到相应的意思。

SGI-STL中关于键值对的定义:

template <class T1, class T2>
struct pair
{
	typedef T1 first_type;
	typedef T2 second_type;
	T1 first;
	T2 second;
	pair(): first(T1()), second(T2())
	{}
	pair(const T1& a, const T2& b): first(a), second(b)
	{}
};

3. 树形结构的关联式容器

在本文中我们介绍,set、multiset、map、multimap、。这四种容器的共同点是:使用平衡搜索树(即红黑树)最为其底层结构,容器中的元素是一个有序的序列。

3.1 set

介绍
set文档介绍
翻译:

  1. set是按照一定次序存储元素的容器
  2. 在set中,元素的value也标识它(value就是key,类型为T),并且每个value必须是唯一的。set中的元素不能在容器中修改(元素总是const),但是可以从容器中插入或删除它们。
  3. 在内部,set中的元素总是按照其内部比较对象(类型比较)所指示的特定严格弱排序准则进行排序。
  4. set容器通过key访问单个元素的速度通常比unordered_set容器慢,但它们允许根据顺序对子集进行直接迭代。
  5. set在底层是用二叉搜索树(红黑树)实现的。

使用

  1. set的模板参数列表
    map和set_第1张图片
  2. 作用:排序+去重
    map和set_第2张图片
    拿么很多人就会问,我们要是想拿set排降序怎么办呢??
    其实很简单:
    map和set_第3张图片
    set迭代器的使用:
    map和set_第4张图片
    总结:
    1 . set中插入元素时,只需要插入value即可,不需要构造键值对。
    2 . set中的元素不可以重复(因此可以使用set进行去重)。
    3. 使用set的迭代器遍历set中的元素,可以得到有序序列。
    4. set中的元素默认按照小于来比较。
    5. set中查找某个元素,时间复杂度为:O(log2N).

3.2 map

介绍:
map文档介绍

翻译

  1. map是关联容器,它按照特定的次序(按照key来比较)存储由键值key和值value组合而成的元素。
  2. 在map中,键值key通常用于排序和惟一地标识元素,而值value中存储与此键值key关联的内容。键值key和值value的类型可能不同,并且在map的内部,key与value通过成员类型value_type绑定在一起,为其取别名称为pair:typedef pair value_type;
  3. 在内部,map中的元素总是按照键值key进行比较排序的。
  4. map中通过键值访问单个元素的速度通常比unordered_map容器慢,但map允许根据顺序对元素进行直接迭代(即对map中的元素进行迭代时,可以得到一个有序的序列)。
  5. map支持下标访问符,即在[]中放入key,就可以找到与key对应的value。
  6. map通常被实现为二叉搜索树(更准确的说:平衡二叉搜索树(红黑树))。

使用:
map的模板参数说明:
map和set_第5张图片
map和set_第6张图片

在使用里面我们要着重掌握 []
map和set_第7张图片

了解了 [] 的作用之后,我们就可以使用 [] 来统计次数
map和set_第8张图片
总结:

  1. map中的的元素是键值对。
  2. map中的key是唯一的,并且不能修改。
  3. 默认按照小于的方式对key进行比较。
  4. map中的元素如果用迭代器去遍历,可以得到一个有序的序列。
  5. map的底层为平衡搜索树(红黑树),查找效率比较高O(log2N)。
  6. 支持[]操作符,operator[]中实际进行插入查找。

3.3 multiset 和multimap

介绍:
multiset/multiimap 和set/map 只有一个大区别就是:multiset与multimap 里面的值可以重复
除了这点,其他可对比于set和map去使用。
map和set_第9张图片

4. OJ练习

前面讲了这么多我们来用题来测试一下!!

题目:
前K个高频单词
map和set_第10张图片
代码展示:

class Solution {
public:
    vector<string> topKFrequent(vector<string>& words, int k) {
        map<string,int>countMap; //定义一个计数map
        for(auto&e:words)
        {
            countMap[e]++; //统计次数(注意[]的作用以及返回值)
        }
        multimap<int,string,greater<int>> sortMap; // 因为有重复的所以使用multimap,
                                                   //并且这里我们排降序(因为要的是高频单词)
        for(auto& e:countMap)
        {
            sortMap.insert(make_pair(e.second,e.first));
        }
        map<int,string>::iterator rit=sortMap.begin();//迭代器的使用
        //auto rit=sortMap.begin();               
        vector<string> v;

        while(k--)
        {
            v.push_back(rit->second); // 然后将前K个插入数组,后面返回
            ++rit;
        }
        return v;

    }
};

你可能感兴趣的:(C++,c++,数据结构)