当前位置: 首页 > news >正文

算法基础知识总结

一.时间复杂度

时间复杂度是衡量算法执行效率的重要指标,它表示算法的运行时间与输入规模之间的增长关系,通常用大 O 符号(O ())表示。

常数阶 O (1) 访问数组中的某个元素(通过索引直接获取)、简单的加减运算
对数阶 O (log n) 每增加一倍输入,操作次数只增加 1 次。(二分查找)
线性阶 O (n) 遍历数组查找元素(一次for循环)
线性对数阶 O (n log n) 高效排序算法(归并排序、快速排序、堆排序等),其核心是 “分治” 思想,每层处理n个元素,共log n
平方阶 O (n²) 双层嵌套循环(如冒泡排序、选择排序)
指数阶 O (2ⁿ) 斐波那契数列(递归)

二.常用排序算法

图示 https://zhuanlan.zhihu.com/p/40695917

算法平均时间复杂度最坏时间复杂度最好时间复杂度空间复杂度稳定性适用场景
冒泡排序O(n²)O(n²)O(n)O(1)稳定小规模数据,教学演示
选择排序O(n²)O(n²)O(n²)O(1)不稳定小规模数据,交换次数少
插入排序O(n²)O(n²)O(n)O(1)稳定小规模或基本有序的数据
希尔排序O(n^1.3~n²)O(n²)O(n)O(1)不稳定中等规模数据
归并排序O(n log n)O(n log n)O(n log n)O(n)稳定大规模数据,要求稳定性
快速排序O(n log n)O(n²)O(n log n)O(log n)不稳定大规模数据,平均性能最优
堆排序O(n log n)O(n log n)O(n log n)O(1)不稳定大规模数据,空间敏感
计数排序O(n + k)O(n + k)O(n + k)O(k)稳定数据范围小且密集
桶排序O(n + k)O(n²)O(n)O(n + k)稳定数据分布均匀
基数排序O(d(n + k))O(d(n + k))O(d(n + k))O(n + k)稳定

初级

冒泡排序:基于比较,每次比较都交换
选择排序:基于比较,提高了冒泡排序的性能,它每遍历一次列表只交换一次数据(min/max保存),即进行一次遍历时找 到最大的项,完成遍历后,再把它换到正确的位置
插入排序:先把前两个排好,第三个插入到前两个合适的位置,依此类推
希尔排序:是插入排序的改进版,划分成多个子列表进行插入排序

高级

归并排序:持续地将一个列表分成两半,最后归并。归并是这样一个过程:把两个排序好了的列表结合在一起组合成一个单一的有序的新列表。元素1,2排好,3,4排好,然后1,2,3,4排序
快速排序:通过一趟排序将要排序的数据分割成独立的两部分(选择一个"基准"),其中一部分的所有数据都比另外一部分的所有数据都要小,然后按照此方法递归直到完成(优化:三路快排)
堆排序:是一种树形选择排序。通过提取未排序的区域内最大的元素并将其移动到已排序的区域来迭代缩小未排序的区域

其他

计数排序
桶排序
基数排序

三.简单数据结构

物理结构:

数组

优点:按照索引查询元素的速度很快;按照索引遍历数组也很方便。
缺点:数组的大小在创建后就确定了,无法扩容;数组只能存储一种类型的数据;添加、删除元素的操作很耗时间,因为要移动其他元素。

链表

优点:不需要初始化容量;可以添加任意元素;插入和删除的时候只需要更新引用。
缺点:含有大量的引用,占用的内存空间大;查找元素需要遍历整个链表,耗时。

数组vs链表

查找:数组O(1) 链表O(n)
插入删除:数组O(n) 链表O(1)

逻辑结构

栈stack

后进先出FILO,入栈push,出栈pop

队列queue

先进先出FIFO,入队出队

双端队列

两端进出

散列表

定义:哈希表是key/value的映射关系,
实现:为了高效查询,用数组实现,把key转化为数组下标的函数就是哈希函数–hash()

哈希冲突
hash()不同的key得到相同数字,解决方案1.开放寻址法ThreadLocal 2.链表法HashMap

HashMap 扩容:负载因子,数组2倍扩容,重新hash

四.树

https://zhuanlan.zhihu.com/p/386991809

根节点,叶子节点;
父节点,孩子节点,兄弟节点;

二叉树

每个节点最多有两个孩子节点;
满二叉树,完全二叉树

结构:链表存储(数据,左孩子,右孩子)

二叉查找树

左节点小于父节点,右节点大于父节点:

插入,查找:

如果待插入数据比根结点的数据小,就去检查根结点的左孩子。如果左孩子不为空,就继续向下检查,如果左孩子为空,就说明已经找到应该插入数据的位置了。向右的情况则与向左的情况互为镜像,只是条件判断的符号换了一下而已。

以(3, 2, 1, 5, 4, 6)的顺序插入-查询时间复杂度O(logn)
在这里插入图片描述
以(1, 2, 3, 4, 5, 6) 和 (6, 5, 4, 3, 2, 1)插入,查询时间复杂度退化成O(n)

遍历:

记:根在前就是前序遍历

遍历方式访问顺序适用场景时间复杂度空间复杂度
前序遍历根 → 左 → 右复制树、前缀表达式O(n)O(h)
中序遍历左 → 根 → 右BST 排序、中缀表达式O(n)O(h)
后序遍历左 → 右 → 根释放内存、后缀表达式O(n)O(h)
层序遍历按层从上到下、从左到右按层处理数据、最短路径(BFS)O(n)O(w)

注:n 为节点数,h 为树的高度(最坏情况 h = n),w 为树的最大宽度。

总结
DFS 与 BFS 的选择:
若需递归处理子树,选 DFS(前 / 中 / 后序)。
若需按层处理,选 BFS(层序)。
迭代与递归:
递归实现简洁,但可能导致栈溢出(如树过深)。
迭代实现需借助栈或队列,避免栈溢出。
遍历用途:
前序遍历常用于复制树结构。
中序遍历是 BST 的天然排序方式。
后序遍历适用于需要子树结果的场景(如动态规划)。
层序遍历常用于按层处理数据或求解最短路径问题。

二叉堆

二叉堆是一棵完全二叉树(除最后一层外,所有层均被填满;最后一层的节点从左到右依次排列,无间隙)。这种结构使其可高效地用数组存储:
所有节点的值需满足以下条件之一:

  • 最大堆(Max Heap):每个父节点的值 ≥ 子节点的值(根节点为最大值)。
  • 最小堆(Min Heap):每个父节点的值 ≤ 子节点的值(根节点为最小值)。

二叉堆的时间复杂度

操作 时间复杂度 说明
插入(Insert) O(log n) 最多上浮 log n 层
删除堆顶 O(log n) 最多下沉 log n 层
构建堆 O(n) 底层节点下沉次数少
查看堆顶 O(1) 直接访问数组第一个元素

二叉堆的应用

  • 优先队列(Priority Queue):
    堆是优先队列的经典实现,支持高效的 “取最值” 和 “插入” 操作,例如:
    任务调度(按优先级执行任务)。霍夫曼编码(频繁合并最小权重节点)。
  • 堆排序(Heap Sort):
    步骤:
    将数组构建为最大堆。
    反复将堆顶(最大值)与末尾元素交换,缩小堆范围并下沉新堆顶,最终得到升序数组。
    堆排序时间复杂度为 O(n log n),但不稳定(相同元素可能交换位置)。
  • Top K 问题:
    例如 “找出数组中前 K 个最大元素”,可通过小顶堆(仅保留 K 个元素)高效实现,时间复杂度 O (n log K)。

二叉堆的局限性

  • 不支持快速查找:堆仅维护最值,查找任意元素需遍历整个数组(O (n))。
  • 删除中间元素效率低:需先查找元素(O (n)),再执行下沉 / 上浮(O (log n)),整体 O (n)。
  • 与其他数据结构对比:
    平衡二叉搜索树(如红黑树)支持更全面的操作(查找、插入、删除均 O (log n)),但实现更复杂。
    斐波那契堆(Fibonacci Heap)理论上插入效率更高(O (1) amortized),但实际应用中因实现复杂较少使用。

AVL 树

自平衡 BST,通过旋转保证左右子树高度差 ≤1,插入 / 删除 / 查找 O (log n)。

红黑树

自平衡 BST,通过颜色标记和旋转保证树的平衡性,插入 / 删除 / 查找 O (log n)。

比较

树结构核心特性典型操作效率核心应用场景
二叉搜索树左小右大,无平衡约束理想 O (log n)简单动态排序查询
AVL 树平衡因子≤1,严格平衡O(log n)高频查询、低频次更新
红黑树颜色规则平衡,弱平衡O(log n)高频更新(如 map/set、进程调度)
B 树多路平衡,节点存数据O(log_m n)磁盘存储(早期数据库索引)
B + 树多路平衡,叶子存数据且链表化O(log_m n)数据库索引(范围查询优先)
字典树共享前缀,字符串存储O(L)前缀匹配、自动补全
哈夫曼树带权路径最短构建 O (n log n)数据压缩(哈夫曼编码)
线段树区间查询与更新O(log n)区间统计(如区间最大值)
http://www.lryc.cn/news/593727.html

相关文章:

  • MYSQL 第一次作业
  • 量子计算与AI融合的技术突破与实践路径
  • scalelsd 笔记 线段识别 本地部署 模型架构
  • 【面试题】大厂高压面经实录丨第三期
  • SpringBoot服装推荐系统实战
  • 石子问题(区间dp)
  • 泛型机制详解
  • Java中缓存的使用浅讲
  • 从代码学习深度强化学习 - SAC PyTorch版
  • openmv小车追小球
  • PCA主成分分析
  • xss-labs1-8题
  • lvs笔记
  • JAVA高级第六章 输入和输出处理(一)
  • python类Keys
  • OpenCV 官翻 2 - 图像处理
  • CAN通信驱动开发注意事项
  • 使用C#对象将WinRiver项目文件进行复杂的XML序列化和反序列化实例详解
  • 软考高级之工程工期成本计算题
  • 用虚拟机体验纯血鸿蒙所有机型!
  • 深入解析LVS负载均衡核心原理
  • Python MCP与Excel增强智能:构建下一代数据处理和自动化解决方案
  • 线性回归问题
  • 【超详细笔记】概率:中心极限定理的直观理解——样本均值为何趋近正态
  • Linux“一切皆文件“设计哲学 与 Linux文件抽象层:struct file与file_operations的架构解析
  • 使用 validation 框架生成一个校验参数是否在枚举内的校验器
  • 环形区域拉普拉斯方程傅里叶级数解
  • DC-DC降压转换5.5V/3A高效率低静态同步降压转换具有自适应关断功能
  • 基于 Google Earth Engine 的 DEM 鞍部自动提取
  • 动态规划——状压DP经典题目