空间适配器:stack、queue(底层是二维数组)、priority_queue(在容器上建立了一个堆结构)在数组上建堆。
多维数组本身也是一维的。vector<vector<int>>
list<vector<int>>list
容器适配器没有提供迭代器。因为它底层就没有提供数据结构。
关联容器:#include <unorderered_set>
#include <unordered_map>
有序关联容器:底层用红黑树实现。
无序的关联容器:
BST树(红黑树)
二分查找就是红黑树的查找。
O(log2n)
红黑树的数据是经过排序的。
L永远在R前面
VLR前序遍历
LVR中序遍历
LRV后序遍历
无序的关联容器,底层是哈希表(链地址法、拉链法)增删查的时间复杂度:接近O(1)。一下子就能找到他。
素数:只有1和本身能整除。不能被其他数这整除。
哈希表的数据结构。(快速的增删查),但数据无序,非常不适合范围查找。
哈希表无序容器。
数据离散一点。解决哈希冲突。
unordered_map:映射表
求散列,
map<int(数),int(重复次数)>:键值
只读没有写操作。定义成常方法。
键值对,用pair打包到一起了。pair对象。需要用户事先将键值对打包好。
类模板会提供函数模板,自动推演这些类型。
函数模板自动推演,自动实例化类对象,返回回来。
定义迭代器:
遍历的顺序和插入的顺序无关,因为哈希表本来就是无序的。
#include <iostream>
#include <unordered_map>
#include <string>
using namespace std;
class Student
{
public:
Student() {}
Student(int id, string name, int age, string sex)
:mId(id), mName(name), mAge(age), mSex(sex) {}
int getId()const { return mId; }
private:
int mId;
string mName;
int mAge;
string mSex;
friend ostream& operator<<(ostream &out, const Student &stu);
};
ostream& operator<<(ostream &out, const Student &stu)
{
out << "id:" << stu.mId << endl;
out << "name:" << stu.mName << endl;
out << "age:" << stu.mAge << endl;
out << "sex:" << stu.mSex << endl;
return out;
}
int main()
{
/*
unordered_map : 映射表
Person
vector<Person> vec; O(n)
unordered_map<int, Person> 哈希表 int(学号)O(1)
*/
//1.创建一组学生对象
Student s1(10000, "刘洋洋", 20, "男");
Student s2(10010, "李鑫", 21, "女");
Student s3(10030, "宁天浩", 19, "男");
unordered_map<int, Student> stuMap;
//2.映射表的插入
stuMap.insert(make_pair(10010, s2));
stuMap.insert(make_pair(10000, s1));
stuMap.insert(make_pair(10030, s3));
//3.遍历映射表
unordered_map<int, Student>::iterator it = stuMap.begin();
for (; it != stuMap.end(); ++it)
{
cout << "key:" << (*it).first << " value:" << it->second << endl;
}
cout << stuMap[10010] << endl;
return 0;
}
在map表中it永远迭代的是pair对象。
关联容器都是通过键值来进行增删改查,把键值组织在红黑树或哈希表中,提高增删改查的效率。
大数据的查重,都离不开哈希表。
写代码一定不能边想边写。(效率太低)一定要先把思路想清楚了再写。
思路还是不清楚啊。
每次写代码前,先将思路在注释里面吧思路写写,不要一上来就写代码,效率太低了。
map表,
写点伪代码。
pair两个变量,一个键值,一个成员值。
打印哈希表肯定是无序的。哈希表本身就是无序的。