C++数据结构
库函数
MAP的生成和遍历
1 | unordered_map<int,int> map; |
构造函数(与结构体同名,冒号后边用于初始化成员变量,大括号用于完成初始化操作如果没有操作可以为空)
1 | struct TreeNode { |
举例
1 | class Person { |
STL:vector
构造函数
1 | vector<int> v; // 创建一个空的vector |
赋值操作
1 | vector<int> v1 = {1, 2, 3}; //int数组初始化int a[3]= {1, 2, 3} |
访问元素
1 | vector<int> v = {10, 20, 30, 40, 50}; |
迭代器
1 | vector<int> v = {1, 2, 3, 4, 5}; |
容量
1 | vector<int> v; |
修改
1 | vector<int> v = {1, 2, 3}; |
在C++中,”reverse”通常指的是将容器(如数组、向量、列表等)中的元素反转顺序,它可以用来反转任何支持双向迭代器的容器。
std::reverse(numbers.begin(), numbers.end());
if (rightNode) 判断一个指针式否为空,为空返回false,不为空返回true。
deque
(双端队列)经常作为stack
和queue
的底层容器使用。
1. stack(栈)
stack
是一个后进先出(LIFO)的数据结构。在STL中,你可以通过以下方式使用它:
声明和初始化
1 | std::stack<int> s; // 默认使用deque作为底层容器 |
主要成员函数
push(const value_type& val)
: 将元素压入栈顶。没有返回值。pop()
: 删除栈顶元素。没有返回值top()
: 返回栈顶元素的引用。如果栈不为空,则返回栈顶元素的引用;如果栈为空,则行为是未定义的(通常会导致程序崩溃)。empty()
: 检查栈是否为空。返回一个布尔值,如果栈为空则返回true
,否则返回false
。size()
: 返回栈中元素的数量。返回一个整数
2. queue(队列)
queue
是一个先进先出(FIFO)的数据结构。在STL中,你可以通过以下方式使用它:
声明和初始化
1 | std::queue<int> q; // 默认使用deque作为底层容器 |
主要成员函数
push(const value_type& val)
: 将元素添加到队列末尾。pop()
: 删除队列的第一个元素。front()
: 返回队列的第一个元素的引用。
back()
: 返回队列的最后一个元素的引用(注意:这不是标准队列操作,但在STL的queue
中提供)。empty()
: 检查队列是否为空。size()
: 返回队列中元素的数量。
3. deque(双端队列)
虽然你提到的是stack
和queue
,但deque
是一个独立的容器,它支持在两端进行插入和删除操作。它可以用作stack
和queue
的底层容器。
声明和初始化
1 | cpp复制代码 |
主要成员函数
push_front(const value_type& val)
: 在双端队列的前端插入元素。push_back(const value_type& val)
: 在双端队列的末尾插入元素。pop_front()
: 删除双端队列的第一个元素。pop_back()
: 删除双端队列的最后一个元素。front()
: 返回双端队列的第一个元素的引用。back()
: 返回双端队列的最后一个元素的引用。empty()
: 检查双端队列是否为空。size()
: 返回双端队列中元素的数量。
哈希数据
- set(集合)
- map(映射)
集合 | 底层实现 | 是否有序 | 数值是否可以重复 | 能否更改数值 | 查询效率 | 增删效率 |
---|---|---|---|---|---|---|
std::set | 红黑树 | 有序 | 否 | 否 | O(log n) | O(log n) |
std::multiset | 红黑树 | 有序 | 是 | 否 | O(logn) | O(logn) |
std::unordered_set | 哈希表 | 无序 | 否 | 否 | O(1) | O(1) |
重点关注实现方式以及查询效率,所以一般情况下我们都使用unordered_set和unordered_map可以提升效率。
映射 | 底层实现 | 是否有序 | 数值是否可以重复 | 能否更改数值 | 查询效率 | 增删效率 |
---|---|---|---|---|---|---|
std::map | 红黑树 | key有序 | key不可重复 | key不可修改 | O(logn) | O(logn) |
std::multimap | 红黑树 | key有序 | key可重复 | key不可修改 | O(log n) | O(log n) |
std::unordered_map | 哈希表 | key无序 | key不可重复 | key不可修改 | O(1) | O(1) |
构造函数
1 | unordered_map<string, int> ageMap; // 创建一个unordered_map,键为string类型,值为int类型 |
1 | map.insert(make_pair("Alice", 30)) |
或者使用map[j] = i;
的语法来插入或更新元素,这里的 map
是一个 unordered_map
的变量名,j
是键(key),i
是值(value)。
插入与更新:如果该键 j
已经存在于 unordered_map
中,则 map[j] = i;
会更新该键对应的值为 i
。如果该键 j
不存在,它会在 unordered_map
中插入一个新元素,键为 j
,值为 i
。
查找
1 | auto it = ageMap.find("Charlie"); |
当你有一个指向map
或unordered_map
中元素的迭代器it
时:
it->first
表示当前元素(键值对)的键。it->second
表示当前元素(键值对)的值。
string字符串
在C++中,std::string
是一个非常有用的类,它表示可变长度的字符串。这个类提供了许多方法来操作字符串。以下是一些常用的std::string
成员函数:
构造函数和析构函数
string()
: 构造一个空的字符串string(const string& str)
: 拷贝构造函数
访问和修改
at(size_t pos)
: 通过索引访问字符,同时进行范围检查front()
: 返回字符串的第一个字符back()
: 返回字符串的最后一个字符+=
: 连接字符串或字符append()
: 在字符串末尾添加字符或字符串push_back(char c)
: 在字符串末尾添加一个字符insert()
: 在指定位置插入字符或字符串erase()
: 删除从指定位置开始的特定数量的字符replace()
: 替换字符串中的一部分swap()
: 交换两个字符串的内容clear()
: 清空字符串内容
字符串信息
size() / length()
: 返回字符串的长度empty()
: 检查字符串是否为空capacity()
: 返回当前分配的存储空间的大小reserve()
: 预留一定的存储空间resize()
: 改变字符串的大小
查找和比较
find()
: 查找子字符串或字符的位置
其他实用函数
substr()
: 返回一个新的字符串,它是此字符串的一个子字符串c_str()
: 返回一个指向正规C字符串的指针, 内容与本字符串相同get_allocator()
: 返回配置器
添加字符
1 | // 方法2: 使用 + 运算符 |
reserve()
: 函数确实遵循左闭右开原则。这是 C++ 标准库中许多函数共有的范围
链表
1 | struct ListNode { |
整行字符串输入
1 | while (getline(cin, s)) { |
一行不确定输入
1 | for (int i = 0; i < n; ++i) { |
1 | //(1)输入数字: |
创建二叉树
优先队列
1 | priority_queue<int, vector<int>, greater<int>> pq; |
第一个是放入的类型,第二个是存储的方式,第三个是从小到大,less是从大到小
没有遍历只有
1 | priority_queue<int, vector<int>, greater<int>> pq; |
自定义比较函数
- 大顶堆:在大顶堆中,父节点的值大于或等于其每个子节点的值。因此,堆的根节点(顶部节点)是堆中的最大值。
- 小顶堆:在小顶堆中,父节点的值小于或等于其每个子节点的值。因此,堆的根节点(顶部节点)是堆中的最小值。
小顶堆的意思是优先队列的头部元素(即队首元素)是最小的。priority_queue默认使用的是大顶堆,也就是说队首元素是最大的
1 | class mycomparison { |
1 | //常规的从小到大排序 |
struct
1 | struct TreeNode { |