一、数据结构基础
1、vector的常用技巧
vector容器擅长在尾部插入或删除元素,在常量中就可以完成,类似于栈。
创建vector方式
vector<int> vector01; // 空容器,没有分配空间
vector<int> vector02(10); // 指定元素个数,默认为0
vector<int> vector03(10, 1); // 指定元素个数,初始值为1
int arr[] = {1, 2, 3};
vector<int> vector04(arr, arr+3); // 通过数组地址初始化
遍历vector方式
vector<int> values(10, 1);
for(auto it = values.begin(); it < values.end(); ++it){ // 迭代器方式
cout << *it << endl;
}
for(int i = 0; i < values.size(); ++i){ // 数组遍历
cout << values[i] << endl;
}
for(auto value : values){ // 基于范围的for循环
cout << value;
}
vecotr用作栈的方式
vector<int> stack; // 初始化栈
int arr[] = {1, 2, 3, 4, 5};
int n = sizeof(arr) / sizeof(arr[0];
for(int i = 0; i < n; ++i){
stack.push_back(arr[i]); // 入栈
}
while(!stack.empty()){
cout << stack.back(); // 获取栈的最顶部元素
stack.pop_back(); // 出栈
}
其它函数
int arr[3] = {1, 2, 3};
vector<int> nums(arr, arr+3);
cout << nums.front() << endl; // 获取vector的首个元素
nums.insert(arr.begin() + 1, 4); // 在第二个位置插入元素,nums为{1, 4, 2, 3}
auto iter = nums.erase(nums.begin() + 1); // 删除第二个元素,nums为{1, 2, 3},返回值为被删元素后一位元素
cout << *iter << endl; // 为2
swap(*(nums.begin() + 1), *(nums.begin() + 2)); // 交换第二个 第三个元素
// 同上 swap(nums[1], nums[2]);
vector的排序
1、升序排序
#include <algorithm>
int arr[] = {2, -1, 1, 3};
vector<int> nums(arr, arr + 4)
sort(nums.begin(), nums.end());
2、降序排序
#include <algorithm>
int arr[] = {2, -1, 1, 3};
vector<int> nums(arr, arr + 4)
sort(nums.rbegin(), nums.rend());
2、deque的常用技巧
与vector不同在于,deque还擅长在序列头部添加或删除元素(并不能保证所有元素存储在连续的内存空间),类似于队列。它可以代替queue,queue可以访问两端,但是只能通过push()实现队尾入队,pop()实现队头弹出;deque也可以访问两端,并且可以在队首和队尾删除和插入元素。
创建、遍历deque方式同vector
deque用作队列的方式
deque <int> q;
q.push_back(1); // 从后端插入队列
q.push_front(2); // 从前端插入队列
cout << q.front() << endl; // 队列的第一个元素
q.pop_front(); // 弹出队列的第一个元素
cout << q.back() << endl; // 队列的最后一个元素
q.pop_back(); // 弹出队列的最后一个元素
cout << q.empty() << endl; // 返回true
3、map和unordered_map用法区别
- 头文件不同
#include <map>
#include <unordered_map>
- 底层实现方式不同
map: 基于红黑树结构实现,故map元素的排列是有序的,但是它的增删改查的复杂度都为O(logn), 同时由于要保存红黑树节点位置,故占用空间也大;
unordered_map: 基于散列表(哈希表)实现的,故它的插入和查询速度为O(1),但是内部排列是无序的,它的占用空间比map的更大!
大部分需要使用字典结构时,都是使用unordered_map
3.1 unordered_map的常用方式
统计每个字母出现的次数
#include <iostream>
#include <string>
#include <unordered_map>
using namespace std;
int main(){
string s1 = "Hello world";
unordered_map<char, int> mp; // Hashmap的创建方式
for(char s : s1){
mp[s]++; // 这里相当于既访问了Hashmap的元素,又加一,mp[s] = mp[s] + 1,故[]在等号右边是访问,在等号左边是赋值
}
// Hashmap的插入方式
// mp.insert(pair<char, int>('x', 2);
// mp['x'] = 2; // 若不加=2,则只是添加key,value为默认的0
// Hashmap的遍历方式
for(auto iter = mp.begin(); iter != mp.end(); ++iter){
cout << iter->first << iter->second << endl;
}
// Hashmap的查找方式
auto iter = mp.find('l'); // 如果查找不到,则mp.find('l') == mp.end()
cout << iter->second; // 输出‘l’的出现次数
return 0;
}
二、其它常用技巧
1、int类型的最大值和最小值
#include <limits.h>
int a = INT_MIN; //-2147483648
int b = INT_MAX; //2147483647