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