点击表格内对应链接跳转对应内容⬇️⬇️⬇️作者主页吃透C语言专栏数据结构Gitee仓库文章目录一算法效率1 算法的复杂度二时间复杂度1 时间复杂度定义2 大O表示法核心规则3 常见时间复杂度从优到差排序三空间复杂度1 空间复杂度定义2 递归与空间复杂度一算法效率项目具体说明算法效率定义评价算法性能优劣的核心指标指算法在解决问题时对计算机系统资源的消耗程度。消耗的资源越少算法效率越高。时间效率算法完成计算所消耗的时间资源直接决定程序运行的快慢。空间效率算法运行过程中占用的内存、缓存等存储资源决定程序对硬件存储的占用程度。1 算法的复杂度算法在编写成可执行程序后运行时需要耗费时间资源和空间(内存)资源。因此衡量一个算法的好坏一般是从时间和空间两个维度来衡量的即时间复杂度和空间复杂度。时间复杂度主要衡量一个算法的运行快慢而空间复杂度主要衡量一个算法运行所需要的额外空间。在计算机发展的早期计算机的存储容量很小。所以对空间复杂度很是在乎。但是经过计算机行业的迅速发展计算机的存储容量已经达到了很高的程度。所以我们如今已经不需要再特别关注一个算法的空间复杂度。二时间复杂度1 时间复杂度定义定义维度具体内容核心含义时间复杂度不是计算代码具体的执行秒数而是衡量代码执行次数随数据量 n 增长的变化规律使用大O表示法来描述这种趋势。程序执行的时候用时间来计时但是程序执行的时间和硬件和程序本身都有关系但是我们的取的是程序本事执行的次数执行的次数决定了程序执行时间的长短和程序执行时间的快慢所以时间复杂度计算的核心就是程序执行的次数2 大O表示法核心规则规则名称规则说明与示例只关注最高阶项2n² 3n 1记为O(n²)忽略常数系数O(3n)简化为O(n)常数时间统一为 O(1)执行次数与数据量无关统一记为O(1)当出现多种情况的话我们取最坏情况的复杂度比如说一个排序如果最开始需要排序的数据原本就是排好的了那么我们的时间复杂度就是O(1),但是如果数据原本就是乱的那时间复杂度就是这个排序算法的时间复杂度可能是O(n),既然有多种情况可能是O(1),可能是O(n),我们取的是最坏的结果也就是O(n)3 常见时间复杂度从优到差排序复杂度名称典型场景增长特性O(1)常数阶数组随机访问、变量赋值不增长O(log n)对数阶二分查找、二叉搜索树查询极慢增长O(n)线性阶数组遍历、单层循环线性增长O(n log n)线性对数阶归并排序、快速排序平均较快增长O(n²)平方阶冒泡排序、双重循环快速增长O(n³)立方阶三重循环、Floyd 最短路算法高速增长O(2ⁿ)指数阶朴素递归斐波那契爆炸增长O(n!)阶乘阶全排列问题超高速爆炸三空间复杂度1 空间复杂度定义衡量算法额外占用内存空间随数据规模 n 增长的趋势。包括了算法创建的数组、对象、变量等额外空间不计算原始输入本身占用的空间除非要求“原地”算法。依然使用大O表示法总结比如一个程序中有一个数组有一个for循环那么这个数组所占的内存并不计入空间复杂度中算法额外占的空间因为空间复杂度明确了是算法额外占用的内存空间也就是这个变量必须是单独为了运行算法这个逻辑占用的空间比如for循环中的初始化变量判断变量调整变量这些变量就是为算法运行而服务的变量也就是算法为了能够运行申请的空间而刚刚说的数组并不是为了支撑算法运行逻辑而申请的空间是正常数据存储的空间不是算法运行逻辑申请的空间总结空间是可能重复利用的也就是说为了算法额外占用的空间如果被重复利用那这个空间只算一次比如int a 申请了一块内存空间我反复使用int a我一直用的都是int a这一块空间所以这一块空间只算一次2 递归与空间复杂度递归调用会占用调用栈空间深度每增加一层就需要分配新的栈帧。如递归求阶乘 factorial(n) 递归深度为 n空间复杂度就是 O(n)而不是 O(1)。总结我们创建两个函数一个A函数一个B函数两个函数的实现是一样的我们先调用A函数再调用B函数调用A函数的栈帧空间开辟以后随着A函数调用结束A函数的栈帧空间被回收但是这一块空间的数据并没有被清楚计算机中没有清除这个概念只有空间权限的概念这块原本属于A的内存空间随着A函数的调用结束使用权限回归到了计算机接下来B函数的调用计算机给B开辟的空间就是刚刚回收的A的空间这块申请过的空间再一次使用只不过使用权给到了B函数而调用的两次函数中都是使用的同一块空间所以被计入空间复杂度的空间调用只有一次因为两次调用用的都是同一块空间点击表格内对应链接跳转对应内容⬇️⬇️⬇️作者主页吃透C语言专栏数据结构Gitee仓库