普及组知识点

- 整型数据类型:如何声明
int
类型的变量并进行赋值和运算。 - 浮点型数据类型:如
float
和double
,了解精度和常见误差。 - 字符型数据类型:
char
类型的使用及 ASCII 编码的基本知识。 - 布尔型数据类型:
bool
类型,常用于逻辑判断,值为true
和false
。 - 算术运算符:
+
、-
、*
、/
、%
的使用,特别是整数除法和取模运算的细节。 - 赋值运算符:
=
、+=
、-=
、*=
、/=
等复合赋值运算符。 - 关系运算符:
==
、!=
、>
、<
、>=
、<=
的使用,常用于条件判断。 - 逻辑运算符:
&&
(与)、||
(或)、!
(非)的组合应用。 - 位运算符:
&
、|
、^
、~
、<<
、>>
,了解基本的二进制位操作。 - 条件判断:
if
语句的基本结构和使用场景。 - 多分支判断:
if-else if-else
的多分支选择逻辑。 switch
语句:在多种情况选择中使用,尤其是常量枚举的选择。for
循环:循环控制结构的使用,掌握基本的迭代方式。while
循环:基于条件的循环控制,理解退出条件。do...while
循环:至少执行一次的循环结构,常见于输入验证。- 循环中的控制语句:
break
和continue
的用法,分别用于跳出循环和跳过某次迭代。 - 数组的定义和初始化:一维数组的声明、初始化和元素访问。
- 二维数组:二维数组的定义和遍历方式,应用于矩阵类问题。
- 字符串的定义:字符数组、字符串的基本操作,包括声明、初始化和输出。
- 字符串操作函数:如
strlen
、strcpy
、strcmp
等标准库函数的使用。 - 字符串拼接:使用
strcat
拼接两个字符串。 - 字符串比较:用
strcmp
比较两个字符串的字典顺序。 - 字符操作:字符的 ASCII 值转换和简单字符操作,如
toupper
和tolower
。 - 输入输出操作:
scanf
和printf
的格式控制,尤其是多变量输入输出。 - 格式化输出:控制输出的小数点位数、宽度对齐等格式。
- 输入输出重定向:如何从文件读取输入和输出到文件,使用
freopen
。 - 常量定义:
#define
宏和const
关键字定义常量。 - 递归函数:递归的定义及其在解决问题中的应用,如汉诺塔问题、斐波那契数列。
- 函数定义与调用:如何定义函数,传递参数,并获取返回值。
- 函数的参数传递:值传递与引用传递的区别。
- 全局变量与局部变量:变量的作用域及生命周期。
- 指针的基础概念:指针的定义、初始化及其与数组的关系。
- 指针运算:指针的加减运算和指向的值的访问。
- 动态内存分配:使用
malloc
和free
动态分配和释放内存。 - 结构体:
struct
的定义和使用,创建复杂数据类型。 - 结构体数组:如何声明结构体数组并操作其成员。
- 枚举类型:
enum
的使用,定义一组命名的常量。 - 时间复杂度:理解常见算法的时间复杂度,如 O(1)、O(n)、O(n^2) 等。
- 空间复杂度:分析算法的空间使用情况。
- 排序算法:掌握冒泡排序、选择排序和插入排序的基本原理和实现。
- 二分查找:在有序数组中实现二分查找的算法,时间复杂度 O(log n)。
- 线性查找:无序数组中的遍历查找算法,时间复杂度 O(n)。
- 冒泡排序的优化:理解如何通过提前终止条件优化冒泡排序。
- 选择排序的实现:基本选择排序的原理与实现步骤。
- 插入排序的实现:了解插入排序的基本原理,适合小规模数组的排序。
- 堆排序:理解二叉堆结构,学习如何进行堆排序,时间复杂度 O(n log n)。
- 递归与回溯:掌握基本递归思想,理解回溯算法的应用,如八皇后问题。
- 动态规划基础:理解分治思想,掌握简单的动态规划问题,如斐波那契数列优化。
- 贪心算法:解决最优子结构问题的贪心策略,如最小硬币找零问题。
- 图的基本表示:掌握邻接矩阵和邻接表表示法,并理解其优缺点。
- 冒泡排序的时间复杂度:最坏情况下冒泡排序的时间复杂度为 O(n²),最好情况下为 O(n)(数组已经有序时)。
- 选择排序的时间复杂度:无论数组是否有序,选择排序的时间复杂度始终为 O(n²)。
- 插入排序的时间复杂度:最坏情况下为 O(n²),最优情况下(数组已经有序)为 O(n)。
- 堆排序的时间复杂度:在平均和最坏情况下,堆排序的时间复杂度为 O(n log n)。
- 二分查找的前提条件:数组必须是有序的,时间复杂度为 O(log n)。
- 线性查找的时间复杂度:无序数组中的查找,时间复杂度为 O(n)。
- 快速排序的时间复杂度:平均时间复杂度为 O(n log n),最坏情况下(每次分割点最偏向一侧)为 O(n²)。
- 归并排序的时间复杂度:归并排序的时间复杂度为 O(n log n),且空间复杂度为 O(n)。
- 递归的时间复杂度分析:如斐波那契数列的递归解法,时间复杂度为 O(2^n),应避免直接使用递归计算大规模斐波那契数。
- 动态规划的时间复杂度:如斐波那契数列的动态规划解法时间复杂度为 O(n),通过记录已计算结果避免重复计算。
- 最大子序和问题:利用动态规划解决最大连续子序和问题,时间复杂度为 O(n)。
- 贪心算法应用:如求解最小硬币找零问题,通过贪心算法选择面值最大的硬币,时间复杂度为 O(n)。
- 深度优先搜索(DFS):使用递归或栈实现的图遍历算法,时间复杂度为 O(V+E)(V 为顶点数,E 为边数)。
- 广度优先搜索(BFS):使用队列实现的图遍历算法,时间复杂度为 O(V+E)。
- 最短路径算法:Dijkstra 算法的时间复杂度为 O(E + V log V),使用优先队列可以优化算法效率。
- 邻接矩阵:图的表示法之一,空间复杂度为 O(V²),适用于稠密图。
- 邻接表:图的另一种表示法,空间复杂度为 O(V+E),适用于稀疏图。
- 回溯算法的时间复杂度:如八皇后问题,时间复杂度为 O(n!)。
- 哈希表的时间复杂度:哈希表在理想情况下查找、插入和删除操作的时间复杂度为 O(1)。
- 哈希冲突解决方法:使用开放地址法或链地址法解决哈希冲突问题。
- 字符串哈希:通过将字符串映射为一个哈希值,常用于字符串匹配问题,时间复杂度为 O(n)。
- 字符串匹配算法:如 KMP 算法,时间复杂度为 O(n + m),n 为文本长度,m 为模式长度。
- 栈的基本操作:栈的
push
(入栈)、pop
(出栈)、top
(获取栈顶元素)操作,时间复杂度均为 O(1)。 - 队列的基本操作:队列的
enqueue
(入队)、dequeue
(出队)、front
(获取队头元素)操作,时间复杂度均为 O(1)。 - 链表的操作:单向链表的插入、删除、遍历操作,时间复杂度为 O(n)。
- 双向链表的操作:双向链表支持从两端操作,插入、删除和遍历的时间复杂度仍为 O(n)。
- 优先队列:基于堆实现的优先队列,插入元素和取出最小(或最大)元素的时间复杂度为 O(log n)。
- 二叉搜索树(BST):查找、插入和删除的平均时间复杂度为 O(log n),最坏情况为 O(n)(当树退化为链表时)。
- 平衡二叉树:如 AVL 树和红黑树,插入、删除和查找的时间复杂度均为 O(log n)。
- Trie 树:用于高效存储和查找字符串的树结构,时间复杂度为 O(m)(m 为字符串长度)。
- 动态数组:如
vector
,插入、删除和访问的时间复杂度分别为 O(n)、O(n) 和 O(1)。 - 常用排序函数:了解 C++ 中的
sort
函数,时间复杂度为 O(n log n)。 - 随机数生成:使用
rand()
生成伪随机数,理解伪随机数生成的原理和范围控制。 - 浮点数精度误差:理解浮点数运算的精度问题,如浮点数比较时要考虑误差(如
fabs(a - b) < 1e-9
)。 - 整除和模运算:掌握取整和取模操作的应用场景,特别是在循环、序列计算中。
- 递归深度限制:理解递归调用时的栈深度限制,避免递归过深导致的栈溢出。
- 动态规划的记忆化搜索:通过保存已经计算过的状态来优化递归算法,避免重复计算。
- 最大公约数(GCD):使用欧几里得算法(辗转相除法)求解两个数的最大公约数,时间复杂度为 O(log(min(a, b)))。
- 最小公倍数(LCM):通过
LCM(a, b) = (a * b) / GCD(a, b)
计算最小公倍数。 - 质数判断:简单的质数判断算法时间复杂度为 O(√n)。
- 埃拉托色尼筛法:高效求解 n 以内所有质数的算法,时间复杂度为 O(n log log n)。
- 乘法逆元:在模运算中,乘法逆元可以通过扩展欧几里得算法计算。
- 模运算:掌握大数运算时如何使用模运算(如取模避免溢出)。
- 位运算的应用:如判断奇偶数(
n & 1
)、快速计算 2 的幂次(1 << k
)等。 - 位掩码:使用位运算处理多个布尔值的组合问题,如集合的子集生成。
- 斐波那契数列的矩阵快速幂:使用矩阵快速幂方法求解斐波那契数列,时间复杂度为 O(log n)。
- 求和公式:掌握常用的求和公式,如等差数列求和、等比数列求和。
- 组合数学基础:如组合数 C(n, k) 的计算公式,以及如何使用动态规划或递归计算组合数。
- 排列与组合:掌握排列 A(n, k) 和组合 C(n, k) 的基本概念及应用。
- 素数分解:将一个数分解为质数因子的算法,时间复杂度为 O(√n)。
- 求 n!(阶乘):通过循环或递归计算 n!,了解其时间复杂度为 O(n)。
- 阶乘尾零的计算:通过计算阶乘中有多少个 10 的倍数,进一步拆解为 2 和 5 的因子对数。
- 斐波那契数列的迭代法:通过迭代计算斐波那契数列,时间复杂度为 O(n),并避免递归造成的栈溢出问题。
- 大数相加:实现多个大整数的加法,可以使用字符串处理模拟大数相加。
- 大数相乘:使用类似竖式的算法模拟大数相乘,时间复杂度为 O(n*m),其中 n 和 m 为两个数的位数。
- 数位和:给定一个整数,计算其各位数字之和,通常通过取模和整除操作实现。
- 位逆序:将一个数的二进制表示反转,如将 1101 变成 1011,常用于位运算题。
- 欧拉函数:计算小于 n 且与 n 互质的整数个数,理解其与质数的关系。
- 前缀和:常用于高效计算数组的某一段区间和,时间复杂度为 O(1)(预处理时间为 O(n))。
- 差分数组:用于快速处理区间加减操作,差分数组在区间修改时可以实现 O(1) 时间复杂度。
- 哈夫曼编码:一种用于数据压缩的贪心算法,通过构建最优前缀码来编码字符,常用于压缩问题。
- 排列的字典序:给定一个排列,求下一个字典序排列的算法(next permutation)。
- ST表:用于解决静态区间最值查询问题,时间复杂度为 O(n log n) 预处理,查询时间复杂度为 O(1)。
- 倍增法:常用于解决 LCA(最近公共祖先)问题,或加速二分查找过程,时间复杂度为 O(log n)。
- 并查集:一种用于动态连通性问题的算法,支持合并集合和判断两个元素是否在同一集合中,时间复杂度为 O(α(n))。
- 路径压缩优化的并查集:通过路径压缩和按秩合并,优化并查集的性能。
- 拓扑排序:用于有向无环图(DAG)中的顶点排序,常用于任务调度问题,时间复杂度为 O(V + E)。
- Kruskal 最小生成树算法:基于边权排序和并查集的最小生成树算法,时间复杂度为 O(E log E)。
- Prim 最小生成树算法:基于贪心策略的最小生成树算法,适用于稠密图,时间复杂度为 O(V²) 或 O(V log V + E)。
- Bellman-Ford 算法:用于解决带负权边的单源最短路径问题,时间复杂度为 O(VE)。
- Floyd-Warshall 算法:用于解决任意两点之间的最短路径问题,时间复杂度为 O(V³)。
- 堆的基本操作:了解如何插入、删除堆顶元素、维护最小(或最大)堆的结构,时间复杂度为 O(log n)。
- 优先队列中的堆实现:C++ 中的
priority_queue
实现堆操作,适用于动态选择最大值或最小值。 - 多重背包问题:在 0-1 背包问题的基础上,考虑每种物品的数量限制,使用动态规划解决,时间复杂度为 O(nW)。
- 完全背包问题:每种物品可以选无限次的背包问题,时间复杂度为 O(nW),W 为背包容量。
- 记忆化搜索:结合递归和缓存技术,避免重复计算子问题,常用于优化递归算法。
- 最长递增子序列(LIS):通过动态规划或二分查找优化求解,时间复杂度分别为 O(n²) 和 O(n log n)。
- 滑动窗口:用于高效处理数组中的区间问题,时间复杂度为 O(n)。
- 双指针法:用于高效处理数组中的特定问题,如有序数组的两数和问题,时间复杂度为 O(n)。
- 最长公共子序列(LCS):使用动态规划解决最长公共子序列问题,时间复杂度为 O(nm)。
- 0-1 背包问题:动态规划解法,时间复杂度为 O(nW),n 为物品数,W 为背包容量。
- 二维数组的动态规划:如最小路径和问题(从左上角到右下角),时间复杂度为 O(mn)。
- 状态压缩动态规划:通过二进制压缩状态信息,常用于 TSP(旅行商)等问题,时间复杂度为 O(n²2ⁿ)。
- 数位 DP:用于处理数位上的问题,如统计满足特定条件的数,常结合递归和动态规划。
- 莫队算法:用于离线查询问题,如区间众数查询,时间复杂度为 O((n + q)√n),q 为查询次数。
- 差分约束系统:解决一类带约束的最短路径问题,常用于时间规划和调度问题。
- Trie树的动态插入与查询:用于字符串集合的存储和快速查询,插入和查询时间复杂度均为 O(k),k 为字符串长度。
- 位操作实现集合子集遍历:通过位操作遍历集合的所有子集,时间复杂度为 O(2ⁿ),n 为集合元素个数。
- 布隆过滤器:通过多个哈希函数实现高效判断元素是否存在,允许一定的误判率。
- 线性筛法:用于高效求解 n 以内的所有质数,时间复杂度为 O(n)。
- 最大流问题:通过网络流模型求解最大流,使用 Edmonds-Karp 算法实现,时间复杂度为 O(VE²)。
- 二分图匹配:使用匈牙利算法解决二分图中的最大匹配问题,时间复杂度为 O(VE)。
- KMP 字符串匹配算法:通过构建部分匹配表(前缀函数)实现快速字符串匹配,时间复杂度为 O(n+m)。
- Manacher 算法:用于在 O(n) 时间内求解字符串中的最长回文子串。
- 动态开点线段树:用于动态维护区间操作,时间复杂度为 O(log n)。
- 线段树的区间修改与查询:常用于处理动态区间查询问题,时间复杂度为 O(log n)。
- 树状数组的单点更新与区间查询:用于解决区间和问题,时间复杂度为 O(log n)。
- 笛卡尔积问题:通过枚举两个集合中的元素对,时间复杂度为 O(n²)。
- 组合数学中的鸽巢原理:用于证明在特定条件下必定存在某种结果,常用于计数问题。
- 容斥原理:用于解决涉及多个集合的计数问题,计算多个事件的并集个数。
- 并查集的路径压缩:通过路径压缩提高并查集的效率,时间复杂度接近 O(1)。
- 按秩合并优化的并查集:在合并两个集合时总是将规模较小的集合合并到较大的集合中,优化效率。
- LCA(最近公共祖先):通过倍增法或 Tarjan 算法解决树中两个节点的最近公共祖先问题,时间复杂度为 O(log n) 或 O(n)。
- 矩阵的转置:将矩阵的行和列互换,常用于图像处理或线性代数问题。
- 矩阵快速幂:用于快速求解矩阵的高次幂,时间复杂度为 O(n³ log k),适用于斐波那契数列的快速计算。
- 高斯消元法:求解线性方程组的算法,时间复杂度为 O(n³),常用于解方程和矩阵问题。
- 最小二乘法:用于解决拟合直线的问题,通过最小化误差平方和来找到最佳拟合直线。
- 叉积和点积:在二维或三维空间中使用向量叉积和点积计算面积、体积或角度。
- 凸包问题:通过 Graham 扫描或 Jarvis 步进法构建平面上的凸包,时间复杂度为 O(n log n)。
- 动态凸包维护:通过数据结构动态维护一组点的凸包,适用于实时更新点集的几何问题。
- 线性规划:通过单纯形法或内点法求解线性规划问题,常用于优化问题。
- 最大公约数和最小公倍数:使用辗转相除法(欧几里得算法)计算两个数的最大公约数和最小公倍数。
- 扩展欧几里得算法:用于解不定方程 ax + by = gcd(a, b) 的整数解,常用于计算乘法逆元。
- 阶乘的素因子分解:计算 n! 中包含的某个素数的幂次,常用于组合数学问题。
- 高精度乘法:通过模拟竖式乘法实现大数相乘,常用于解决乘积超出常规数据类型范围的问题。
- 高精度除法:通过模拟竖式除法实现大数除法,解决超大整数的整除运算。
- 快速排序的随机化优化:通过随机选择枢轴元素,避免最坏情况下的 O(n²) 时间复杂度。
- 三路快排:对数组中含有大量重复元素的情况进行优化,时间复杂度为 O(n log n)。
- 希尔排序:基于插入排序的改进版,通过逐步减小步长的插入排序提高效率,时间复杂度为 O(n log² n)。
- 桶排序:用于分布范围较为均匀的数列,时间复杂度为 O(n + k)。
- 基数排序:通过逐位比较进行排序,适用于非负整数的排序,时间复杂度为 O(nk),k 为整数位数。
- 计数排序:适用于整数范围较小的情况,时间复杂度为 O(n + k),k 为整数的最大值。
- 弗洛伊德环检测算法:检测链表中是否存在环,并找到环的起点,时间复杂度为 O(n)。
- 双向广度优先搜索:在图的搜索中同时从起点和终点开始搜索,减少搜索空间,时间复杂度为 O(b^(d/2)),其中 b 是分支因子,d 是搜索深度。
- 双端队列(Deque):一种允许从两端插入和删除元素的队列,常用于滑动窗口问题。
- STL 容器的使用:了解 C++ 中常用的 STL 容器,如
vector
、map
、set
、stack
、queue
等,掌握其基本操作和时间复杂度。 - 动态数组扩容机制:了解动态数组(如
vector
)的自动扩容机制及其对时间复杂度的影响,摊还时间复杂度为 O(1)。 - 链表与数组的区别:链表的插入和删除时间复杂度为 O(1),但访问时间复杂度为 O(n),而数组的随机访问时间复杂度为 O(1)。
- 环形链表:通过设置链表的尾节点指向头节点构成环形链表,常用于循环调度问题。
- 栈的应用:如使用栈解决括号匹配问题,或者在递归问题中模拟系统调用栈。
- 单调栈:用于解决某些区间问题,如求数组中每个元素右边第一个比它大的元素,时间复杂度为 O(n)。
- 单调队列:用于求解滑动窗口的最值问题,时间复杂度为 O(n)。
- 线性探测法:处理哈希冲突的一种方式,在发生冲突时线性探测下一个空闲位置。
- 二次探测法:处理哈希冲突的一种方式,通过二次探测来避免聚集冲突。
- 二分法的实际应用:如在数列中查找满足某条件的最小值或最大值。
- 以空间换时间的技巧:通过预处理存储中间结果来提高查询效率,如使用前缀和数组或缓存递归结果。
- 整数拆分问题:将一个整数拆分为若干个正整数之和的方案数,使用动态规划解决。
- 最大矩形面积问题:在一个二维矩阵中找出只包含 1 的最大矩形面积,时间复杂度为 O(nm)。
- 最大正方形问题:求二维矩阵中只包含 1 的最大正方形面积,时间复杂度为 O(nm)。
- 子集和问题:判断给定的集合中是否存在一个子集,其元素之和等于给定值,使用动态规划解决。
- 数独解题:使用回溯算法解决数独问题,理解剪枝技巧的应用。
- 八皇后问题:使用回溯算法在 8x8 的棋盘上放置 8 个皇后,使它们互相不能攻击,时间复杂度为 O(n!)。
- 最小编辑距离:通过动态规划求解两个字符串的最小编辑距离,时间复杂度为 O(nm)。
- 分治法:将问题分成若干子问题,分别解决后合并子问题的解,适用于求解大规模问题,如归并排序。
- 分治法的递归树分析:通过递归树分析分治算法的时间复杂度,如
T(n) = 2T(n/2) + O(n)
的时间复杂度为 O(n log n)。 - 最大流 Dinic 算法:一种求解最大流问题的高效算法,时间复杂度为 O(V²E)。
- 可持久化数据结构:如可持久化线段树,支持查询历史版本的操作,时间复杂度为 O(log n)。
- K-D 树:一种用于解决多维空间最近邻查询问题的数据结构,时间复杂度为 O(log n)。
- 线性基:用于解决位运算问题,如求解最大异或和,时间复杂度为 O(n)。
- 位图:一种高效的存储大量布尔值的数据结构,适用于处理大规模数据集合。
- 组合数公式:组合数 C(n, k) 的公式为 C(n, k) = n! / (k! * (n - k)!),可以用于计算从 n 个元素中选取 k 个元素的方案数。
- 组合数的递推关系:组合数可以通过递推公式 C(n, k) = C(n-1, k-1) + C(n-1, k) 进行计算,常用于动态规划。
- 组合数的递归计算:可以通过递归实现组合数的计算,但效率较低,通常用于小规模问题。
- 杨辉三角(帕斯卡三角形):利用动态规划构建杨辉三角,可以在 O(n²) 时间内计算出所有组合数。
- 快速计算组合数:通过预处理阶乘和逆元数组,可以在 O(1) 时间内计算组合数,预处理时间为 O(n)。
- 组合数取模:由于组合数值很大,常需要将其结果对一个大质数取模,通常使用费马小定理来处理除法取模问题。
- **排列数 A(n, k)**:排列数公式 A(n, k) = n! / (n - k)!,表示从 n 个元素中选取 k 个排列的方案数。
- 全排列生成:使用递归或 STL 的
next_permutation
函数生成一个数组的所有全排列,时间复杂度为 O(n!)。 - 重复元素的排列:处理包含重复元素的全排列时,需要去重,可以通过排序加跳过相同元素实现。
- 组合的生成:利用递归或二进制枚举的方法生成从 n 个元素中选取 k 个元素的所有组合,时间复杂度为 O(C(n, k))。
- 与运算(&):
a & b
是按位与运算,结果是两个数对应位上都为 1 时取 1,否则取 0,常用于掩码操作。 - 或运算(|):
a | b
是按位或运算,结果是两个数对应位上有一个为 1 时取 1,常用于合并标志位。 - 异或运算(^):
a ^ b
是按位异或运算,结果是对应位上不相同时取 1,相同时取 0,常用于交换两个变量或找出不成对的数。 - 取反运算(~):
~a
是按位取反运算,将 a 的所有位都取反,1 变 0,0 变 1。 - 左移运算(<<):
a << b
是将 a 的二进制表示左移 b 位,等价于 a 乘以 2 的 b 次方,时间复杂度为 O(1)。 - 右移运算(>>):
a >> b
是将 a 的二进制表示右移 b 位,等价于 a 除以 2 的 b 次方,时间复杂度为 O(1)。 - 快速计算 2 的幂:通过左移运算可以快速计算 2 的幂,如
1 << n
表示 2 的 n 次方。 - 判断奇偶性:通过
n & 1
可以判断 n 是奇数还是偶数,1 表示奇数,0 表示偶数。 - 清除最低位的 1:
n & (n - 1)
可以快速清除 n 的二进制表示中最低位的 1,常用于统计二进制中 1 的个数。 - 二进制中 1 的个数:通过不断使用
n & (n - 1)
可以在 O(log n) 时间内统计 n 的二进制表示中 1 的个数。 - 位掩码:通过与运算和或运算,可以使用位掩码来处理多个布尔变量,常用于状态压缩。
- 二进制枚举:利用二进制数的位来表示选取的元素,可以用来枚举所有子集,时间复杂度为 O(2ⁿ),n 为集合大小。
- 交换两个变量:使用异或运算
a = a ^ b; b = a ^ b; a = a ^ b;
可以在不使用临时变量的情况下交换 a 和 b。 - 取二进制的某一位:
(a >> k) & 1
可以得到 a 的二进制表示中第 k 位的值(0 或 1)。 - 设置二进制的某一位:
a | (1 << k)
可以将 a 的二进制表示中的第 k 位设置为 1。 - 清除二进制的某一位:
a & ~(1 << k)
可以将 a 的二进制表示中的第 k 位设置为 0。 - 翻转二进制的某一位:
a ^ (1 << k)
可以将 a 的二进制表示中的第 k 位取反。 - 位运算加法:使用
a ^ b
(不进位加法)和(a & b) << 1
(进位)可以模拟二进制加法。 - 位运算乘法:通过位移和加法,可以模拟二进制乘法,如
a << 1
等价于a * 2
。 - 位运算除法:通过右移可以模拟二进制除法,如
a >> 1
等价于a / 2
。 - 二叉树的定义:二叉树是一种每个节点最多有两个子节点的数据结构,分别称为左子节点和右子节点。
- 二叉树的遍历:包括前序遍历(根-左-右)、中序遍历(左-根-右)和后序遍历(左-右-根),可以递归或迭代实现。
- 二叉树的层次遍历:通过使用队列实现二叉树的层次遍历(广度优先遍历),每次访问一层的节点。
- 满二叉树:如果一棵二叉树的所有节点都有 0 或 2 个子节点,并且所有叶节点都在同一层,则称为满二叉树。
- 完全二叉树:完全二叉树的每一层除了最后一层是满的,并且最后一层的节点从左到右连续排列。
- 平衡二叉树:一种特殊的二叉树,要求左右子树的高度差不能超过 1,常用于提高查找效率。
- 二叉搜索树(BST):一种特殊的二叉树,满足每个节点的左子树的值都小于该节点的值,右子树的值都大于该节点的值。
- 二叉搜索树的查找:在二叉搜索树中查找某个值的时间复杂度为 O(log n),最坏情况下为 O(n)。
- 二叉搜索树的插入:向二叉搜索树中插入一个新值,时间复杂度为 O(log n),最坏情况下为 O(n)。
- 二叉搜索树的删除:在二叉搜索树中删除某个节点,分为删除叶子节点、单子树节点和双子树节点三种情况。
- 二叉搜索树的最小值和最大值:二叉搜索树中最小值位于最左边的节点,最大值位于最右边的节点。
- 二叉搜索树的中序遍历结果:二叉搜索树的中序遍历结果是一个升序排列的序列。
- 二叉树的高度:通过递归或迭代计算二叉树的高度,时间复杂度为 O(n)。
- 二叉树的最大路径和:利用递归计算二叉树中任意两节点之间的最大路径和,时间复杂度为 O(n)。
- 二叉树的深度:通过递归或迭代计算二叉树的深度,时间复杂度为 O(n)。
- 平衡二叉树的判定:通过递归检查每个节点的左右子树高度差是否超过 1,时间复杂度为 O(n)。
- AVL树:一种自平衡二叉搜索树,通过旋转操作保持树的平衡,插入和删除的时间复杂度为 O(log n)。
- 红黑树:一种近似平衡的二叉搜索树,红黑树的插入、删除和查找的时间复杂度均为 O(log n)。
- 堆:堆是一棵完全二叉树,分为最大堆(每个节点的值大于等于子节点)和最小堆(每个节点的值小于等于子节点),常用于优先队列。
- 堆的插入和删除:在堆中插入一个新元素或删除堆顶元素,时间复杂度为 O(log n)。
计算机网络
OSI 七层模型:包括物理层、数据链路层、网络层、传输层、会话层、表示层和应用层,各层负责的功能不同。
TCP/IP 模型:分为四层,包括网络接口层、网络层、传输层和应用层,是互联网通信的基础协议。
IP 地址:用于唯一标识网络中的每一台主机,分为 IPv4 和 IPv6,IPv4 是 32 位地址,IPv6 是 128 位地址。
IPv4 地址分类:包括 A 类、B 类、C 类、D 类和 E 类,分别用于不同规模的网络。
子网掩码:用于划分网络中的子网,常见的子网掩码如 255.255.255.0 表示前 24 位为网络部分。
DHCP 协议:动态主机配置协议,用于自动为设备分配 IP 地址。
NAT(网络地址转换):用于在路由器或防火墙上将私有 IP 地址转换为公有 IP 地址,以便多个设备通过一个公共 IP 地址访问互联网。
DNS(域名系统):用于将域名解析为 IP 地址,常见的 DNS 服务器如 Google 的 8.8.8.8。
TCP(传输控制协议):一种面向连接的、可靠的传输协议,提供数据包的顺序传输和确认机制。
UDP(用户数据报协议):一种无连接的、不可靠的传输协议,常用于实时通信、视频流等场景。
TCP 三次握手:建立 TCP 连接的过程,客户端和服务器之间通过 SYN 和 ACK 报文进行三次通信。
TCP 四次挥手:断开 TCP 连接的过程,通过 FIN 和 ACK 报文进行四次通信。
流量控制:TCP 使用窗口机制进行流量控制,防止发送方发送过多数据超出接收方的处理能力。
拥塞控制:TCP 的拥塞控制机制通过慢启动、拥塞避免、快速重传和快速恢复来避免网络拥塞。
HTTP 协议:超文本传输协议,用于 Web 浏览器与服务器之间的通信,常用端口号为 80。
HTTPS 协议:在 HTTP 协议的基础上增加了 SSL/TLS 加密,提供安全的数据传输,常用端口号为 443。
SSL/TLS 协议:用于加密网络通信,确保数据在传输过程中不被窃听和篡改。
FTP 协议:文件传输协议,用于在客户端和服务器之间传输文件,常用端口号为 21。
SMTP 协议:简单邮件传输协议,用于发送电子邮件,常用端口号为 25。
POP3 和 IMAP 协议:用于接收电子邮件,POP3 常用端口号为 110,IMAP 常用端口号为 143。
DNS 解析流程:浏览器向 DNS 服务器发送查询请求,DNS 服务器返回对应的 IP 地址。
ICMP 协议:用于发送网络诊断和错误消息,常见应用如
ping
和traceroute
。ping 命令:用于测试主机之间的网络连通性,基于 ICMP 协议。
traceroute 命令:用于显示数据包在网络中经过的路由节点,帮助诊断网络问题。
ARP 协议:地址解析协议,用于将 IP 地址映射为物理地址(MAC 地址),在局域网中使用。
MAC 地址:网卡的物理地址,是全球唯一的,通常由 48 位二进制数表示。
交换机的工作原理:交换机工作在数据链路层,用于在局域网中转发数据包,根据 MAC 地址进行转发。
路由器的工作原理:路由器工作在网络层,用于在不同的网络之间转发数据包,根据 IP 地址进行路由选择。
路由表:路由器用于选择下一跳路由的表格,包含网络目标、子网掩码、网关和接口等信息。
默认网关:当数据包的目标 IP 地址不在当前子网内时,发送到默认网关,由其转发到其他网络。
防火墙:网络安全设备,用于监控和控制进出网络的流量,根据预定义的规则允许或阻止流量。
代理服务器:中介服务器,客户端通过代理服务器访问其他服务器,常用于缓存和隐藏 IP 地址。
负载均衡:通过分发网络流量到多个服务器上,提升服务的可靠性和性能。
VPN(虚拟专用网络):通过加密隧道技术,允许用户安全地通过公共网络访问私有网络。
数据包的结构:数据包包含头部(header)和数据部分,头部包含源 IP、目标 IP、源端口、目标端口等信息。
MTU(最大传输单元):在网络上传输的最大数据包大小,常见的 MTU 值为 1500 字节。
数据包的分片与重组:当数据包的大小超过 MTU 时,需要进行分片,接收方负责将分片的数据包重新组装。
粘包与拆包:在 TCP 协议中,由于数据流的连续性,可能会出现粘包或拆包现象,常通过增加头部信息或定长包处理。
操作系统
操作系统的功能:操作系统负责管理硬件资源、提供用户接口、控制程序执行,并进行文件系统管理。
进程和线程的区别:进程是程序的运行实例,线程是进程中的最小执行单位,多个线程共享同一进程的资源。
进程的状态:进程有三种主要状态:就绪状态、运行状态和等待状态。
进程调度算法:包括先来先服务(FCFS)、短作业优先(SJF)、优先级调度和轮转调度(RR)等。
线程的创建与终止:线程可以通过
pthread_create
(Linux)或CreateThread
(Windows)创建,执行完成后会自动终止。多线程的并发与并行:并发是指多个线程交替执行,并行是指多个线程同时执行,后者需要多核 CPU 支持。
死锁:当多个进程或线程互相等待对方释放资源,导致所有进程都无法继续执行,形成死锁。
死锁的必要条件:互斥、持有并等待、不可抢占、循环等待。
死锁的解决方法:可以通过预防、避免、检测和解除死锁来解决,如银行家算法用于避免死锁。
内存管理:包括分段和分页管理方式,用于有效利用物理内存,防止内存碎片。
虚拟内存:通过页表将物理内存与虚拟地址空间映射,使得程序可以使用比实际物理内存更大的内存空间。
分页机制:操作系统将内存划分为等大小的页(page)和页框(frame),通过页表管理内存的分配。
页面置换算法:用于决定当内存不足时应将哪一页调出内存,包括 FIFO、LRU 和 OPT 等算法。
文件系统的功能:负责文件的创建、删除、读写和权限管理,常见的文件系统如 FAT32、NTFS 和 EXT4。
I/O 管理:操作系统通过驱动程序管理设备 I/O 操作,提供缓冲、队列和设备独立性。
中断处理机制:操作系统通过中断处理程序响应硬件和软件的中断请求,确保程序的正常执行。
时钟中断:用于操作系统的定时调度和资源管理,周期性地触发进程调度。
文件的权限管理:通过读、写、执行权限控制用户对文件的访问,Linux 中常用的权限表示为 rwx。
进程间通信(IPC):包括管道(pipe)、消息队列、共享内存和信号量,用于进程之间的数据交换。
信号量:用于解决多进程或多线程的同步与互斥问题,常用于实现生产者-消费者模型。
自旋锁:一种用于多线程同步的锁机制,线程在等待锁时不会进入睡眠,而是忙等待。
条件变量:用于线程之间的同步,线程可以在条件变量上等待特定条件满足后继续执行。
信号机制:操作系统通过信号通知进程某些事件的发生,进程可以捕获和处理信号,如
SIGINT
、SIGKILL
等。页表的多级结构:为了减少页表的存储开销,使用多级页表,每一级页表都只存储部分虚拟地址空间的映射关系。
硬链接和软链接:硬链接是指向文件数据的多个目录项,软链接是指向另一个文件路径的符号链接。
优先级反转:低优先级的进程占有资源而高优先级进程等待,可能会导致优先级反转问题。
分时系统:通过时间片轮转的方式为每个用户分配 CPU 使用权,提高系统响应能力。
- Title: 普及组知识点
- Author: YZY
- Created at : 2025-06-17 00:10:38
- Updated at : 2025-06-17 00:10:38
- Link: https://blog.dtoj.team/2025/06/17/CSP普及组知识点/
- License: This work is licensed under CC BY-NC-SA 4.0.