一、map

1、map成员

map成员

上面可以看到Map接口的几个实现方式。简要说明:

TreeMap是基于树(红黑树)的实现方式,即添加到一个有序列表,在O(log n)的复杂度内通过key值找到value,优点是空间要求低,但在时间上不如HashMap。C++中Map的实现就是基于这种方式

HashMap是基于HashCode的实现方式,在查找上要比TreeMap速度快,添加时也没有任何顺序,但空间复杂度高。C++ unordered_Map就是基于该种方式。

HashTable与HashMap类似,只是HashMap是线程不安全的,HashTable是线程安全的,现在很少使用

ConcurrentHashMap也是线程安全的,但性能比HashTable好很多,HashTable是锁整个Map对象,而ConcurrentHashMap是锁Map的部分结构。

 

2、map简介

map时STL的一个关联容器,它提供一对一的hash。第一个模板参数可以称为关键字key,每个关键字只能在map中出现一次;第二个模板参数可以称为value。

map以模板(泛型)方式实现,可以存储任意类型的数据,包括使用者自定义的数据类型。Map主要用于资料一对一映射的情况,在map内部所有的数据都是有序的。

 

3、map的功能和使用

自动建立key--value的对应,key和value可以是任意你需要的类型。

使用map需要包含map类所在头文件:

#include <map>    //STL头文件时没有扩展名.h的

map对象时模板类,需要关键字和存储对象两个模板参数:

std::map<int,string> school;

这里定义了一个用int作为索引,并拥有相关联的指向string的指针。

 

3、map的构造函数

a.插入元素

//定义一个map对象
std::map<int,string> school;

//第一种,用insert函数插入pair
school.insert(pair<int,string>(0,"zero"));

//第二种,用insert函数插入value_type数据
school.insert(map<int,string>::value_type(1,"one"));

//第三种,用array方法插入
school[2] = "two";
school[3] = "three";

b、查找元素

//当所查找的关键字key出现时,它返回数据所在对象的位置,如果没有,返回iter与end函数的值相同
//利用find返回指向当前查找元素的位置的迭代器,找不到则返回map::end()位置
iter = school.find("1");
if(iter != school.end())
    cout<<"the value is"<<iter->second<<endl;
esle
    cout<<"do not find"<<endl;

c、删除与清空元素

//迭代器删除
iter = school.find("2");
school.erase(iter);

//用关键字删除,删除成功返回1,否则返回0;
int n = school.erase("2);

//用迭代器范围删除
school.erase(school.begin(),school.end());  //将整个school清空

d、map的基本操作函数

     begin()         //返回指向map头部的迭代器

     clear()        //删除所有元素

     count()         //返回指定元素出现的次数

     empty()         //如果map为空则返回true

     end()           //返回指向map末尾的迭代器

     equal_range()   //返回特殊条目的迭代器对

     erase()         //删除一个元素

     find()          //查找一个元素

     get_allocator() //返回map的配置器

     insert()        //插入元素

     key_comp()      //返回比较元素key的函数

     lower_bound()   //返回键值>=给定元素的第一个位置

     max_size()      //返回可以容纳的最大元素个数

     rbegin()        //返回一个指向map尾部的逆向迭代器

     rend()          //返回一个指向map头部的逆向迭代器

     size()          //返回map中元素的个数

     swap()           //交换两个map

     upper_bound()    //返回键值>给定元素的第一个位置

     value_comp()     //返回比较元素value的函数


 

二、HashMap

HashMap简介

HashMap简称哈希表,主要思想和流程如下:

HashMap在添加值时需要给定两个参数,一个是key,一个是value。为了能很快的通过key值找到对应的value,因此有必要建立一个key值和内存指针的映射,举个简单的例子,如果说key值是int型,那么其实最简单的方式就是定义一个数组,以这个key值作为下标,value作为内存中的值。然而由于key值可能会很大,或者是string或着其他类型的值,因此就不能单纯的简单对应了,这时候就需要做一个转换。这个在Java和C#中是通过一个int HashCode()的函数实现的。具体的实现可能是通过地址、字符串或数字算出来的值,然后如果是自己定义的对象,则需要自己实现HashCode()和equal().

注意,hashcode的实现需要满足以下要求:

a、如果两个对象equals相等,那么这两个对象的HashCode一定也相同

b、如果两个对象的HashCode相同,不代表两个对象就相同,只能说明这两个对象在散列存储结构中,存放于同一个位置

 

hash_map(size_type n) 如果讲究效率,这个参数是必须要设置的。n 主要用来设置hash_map 容器中hash桶的个数。桶个数越多,hash函数发生冲突的概率就越小,重新申请内存的概率就越小。n越大,效率越高,但是内存消耗也越大。

const_iterator find(const key_type& k) const. 用查找,输入为键值,返回为迭代器。

data_type& operator[](const key_type& k) . 这是我最常用的一个函数。因为其特别方便,可像使用数组一样使用。不过需要注意的是,当你使用[key ]操作符时,如果容器中没有key元素,这就相当于自动增加了一个key元素。因此当你只是想知道容器中是否有key元素时,你可以使用find。如果你希望插入该元素时,你可以直接使用[]操作符。

insert 函数。在容器中不包含key值时,insert函数和[]操作符的功能差不多。但是当容器中元素越来越多,每个桶中的元素会增加,为了保证效率,hash_map会自动申请更大的内存,以生成更多的桶。因此在insert以后,以前的iterator有可能是不可用的。
erase 函数。在insert的过程中,当每个桶的元素太多时,hash_map可能会自动扩充容器的内存。但在sgi stl中是erase并不自动回收内存。因此你调用erase后,其他元素的iterator还是可用的。

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐