std::Map、unordered_map

1.0 Map

std::map的底层实现是基于红黑树的,这是一种高度平衡的二叉搜索树。这种数据结构使得map在进行查找时的效率非常高。此外,map的插入操作对其他节点的干扰非常小,这得益于它在插入新节点时会通过哈希函数找到相应的位置,然后更新链表,从而避免了整个树结构的移动。
+ 键值对存储:以键作为唯一标识符,快速定位到对应的值。
+ 二叉搜索树实现:底层使用红黑树,提高查找效率。
+ map的赋值操作(map_a = map_b)是通过深拷贝实现的深拷贝赋值:确保元素之间不共享内存。
+ 高效查找:通过哈希函数快速定位,减少遍历树的操作。
+ 键唯一性:防止键重复,保持映射数据的完整性和一致性。
数据的遍历
数据的遍历,提供三种方法,对map进行遍历
第一种:应用前向迭代器,for(iter = mapStudent.begin(); iter != mapStudent.end(); iter++)
第二种:应用反相迭代器,for(iter = mapStudent.rbegin(); iter != mapStudent.rend(); iter++)
第三种:用数组方式 int nSize = mapStudent.size();for(int nIndex = 1; nIndex <= nSize; nIndex++)
数据的查找
第一种:用count函数来判定关键字是否出现,其缺点是无法定位数据出现位置, 由于map的特性,一对一的映射关系,就决定了count函数的返回值只有两个,要么是0,要么是1.

第二种:用find函数来定位数据出现位置,它返回的一个迭代器,当数据出现时,它返回数据所在位置的迭代器,如果map中没有要查找的数据,它返回的迭代器等于end函数返回的迭代器.

第三种:
   Lower_bound函数用法,这个函数用来返回要查找关键字的下界(是一个迭代器)
   Upper_bound函数用法,这个函数用来返回要查找关键字的上界(是一个迭代器)
排序
排序问题,STL中默认是采用小于号来排序的,
因为关键字是int型,它本身支持小于号运算,在一些特殊情况,比如关键字是一个结构体,涉及到排序就会出现问题,
因为它没有小于号操作,insert等函数在编译的时候过不去,下面给出两个方法解决这个问题
#include <map>
#include <string>
Using namespace std;

Typedef struct tagStudentInfo
{
       Int      nID;
       String   strName;
       Bool operator < (tagStudentInfo const& _A) const
       {
              //这个函数指定排序策略,按nID排序,如果nID相等的话,按strName排序
              If(nID < _A.nID)  return true;
              If(nID == _A.nID) return strName.compare(_A.strName) < 0;
              Return false;
       }
}StudentInfo, *PStudentInfo;  //学生信息

Int main()
{
	int nSize;
	 //用学生信息映射分数
	 map<StudentInfo, int>mapStudent;
	 map<StudentInfo, int>::iterator iter;

	 StudentInfo studentInfo;
	 studentInfo.nID = 1;
	 studentInfo.strName = “student_one”;
	 mapStudent.insert(pair<StudentInfo, int>(studentInfo, 90));

	 studentInfo.nID = 2;
	 studentInfo.strName = “student_two”;
	 mapStudent.insert(pair<StudentInfo, int>(studentInfo, 80));
}

2.0 unordered_map

  1. 关联容器(associative container),可以用来快速存储和访问键值对(key-value pairs)。它的底层实现采用哈希表(hash table)算法,可以在常数时间复杂度下进行插入、查找、删除、修改等操作。

  2. 该函数会根据给定的键k,在unordered_map中查找对应的值,并返回一个对该值的引用。如果unordered_map中没有该键,则函数会抛出一个out_of_range异常。

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

int main() {
    unordered_map<string, int> my_map = {
        {"Alice", 18},
        {"Bob", 20},
        {"Charlie", 22}
    };

    my_map.at("Alice") = 19;
    my_map.at("Bob") += 1;
    my_map.at("Charlie")++;

    cout << "Alice's age is " << my_map.at("Alice") << endl;
    cout << "Bob's age is " << my_map.at("Bob") << endl;
    cout << "Charlie's age is " << my_map.at("Charlie") << endl;
    return 0;
}
#include <iostream>
#include <unordered_map>
#include <stdexcept>

using namespace std;

int main() {
    unordered_map<string, int> my_map = {
        {"Alice", 18},
        {"Bob", 20},
        {"Charlie", 22}
    };
    try {
        cout << "David's age is " << my_map.at("David") << endl;
    } catch (const out_of_range& oor) {
        cerr << "David's age not found in map: " << oor.what() << endl;
    }
    return 0;
}

bucket()函数可以获取某个元素所在的桶的编号

#include <iostream>
#include <unordered_map>
using namespace std;
int main(){
    unordered_map<string, int> umap;
    umap["Leo"] = 90;
    umap["Tom"] = 80;
    umap["Lucy"] = 70;
    cout << "Lucy is in bucket #" << umap.bucket("Lucy") << endl;
    cout << "Tom is in bucket #" << umap.bucket("Tom") << endl;
    cout << "Leo is in bucket #" << umap.bucket("Leo") << endl;
    return 0;
}

Lucy is in bucket #1
Tom is in bucket #0
Leo is in bucket #2
posted @ 2018-06-20 23:10  osbreak  阅读(334)  评论(0编辑  收藏  举报