java数据结构基础:时间和空间复杂度

一.算法效率:

算法效率分析分为两种:第一种是时间效率,第二种是空间效率。时间效率被称为时间复杂度,而空间效率被称作空间复杂度。

时间复杂度主要衡量的是一个算法的运行速度,而空间复杂度主要衡量一个算法所需要的额外空间,在计算机发展的早期,计算机的存储容量很小。所以对空间复杂度很是在乎。但是经过计算机行业的迅速发展,计算机的存储容量已经达到了很高的程度。所以我们如今已经不需要再特别关注一个算法的空间复杂度。

二.时间复杂度:

①时间复杂度的定义:在计算机科学中,算法的时间复杂度是一个数学函数,它定量描述了该算法的运行时间。一个算法执行所耗费的时间,从理论上说,是不能算出来的,只有你把你的程序放在机器上跑起来,才能知道。但是我们需要每个算法都上机测试吗?是可以都上机测试,但是这很麻烦,所以才有了时间复杂度这个分析方式。一个算法所花费的时间与其中语句的执行次数成正比例,算法中的基本操作的执行次数,为算法的时间复杂度。

②大O的渐进表示法:

实际中我们计算时间复杂度时,我们其实并不一定要计算精确的执行次数,而只需要大概执行次数,那么这里我们使用大O的渐进表示法。

1、用常数1取代运行时间中的所有加法常数。
2、在修改后的运行次数函数中,只保留最高阶项。
3、如果最高阶项存在且不是1,则去除与这个项目相乘的常数。得到的结果就是大O阶

另外有些算法的时间复杂度存在最好、平均和最坏情况:
最坏情况:任意输入规模的最大运行次数(上界)
平均情况:任意输入规模的期望运行次数
最好情况:任意输入规模的最小运行次数(下界)

③常见时间复杂度计算举例

// 计算func2的时间复杂度? void func2(int N) { int count = 0; for (int k = 0; k < 2 * N ; k++) { count++; } int M = 10; while ((M--) > 0) { count++; } System.out.println(count); }
(1)for 循环的执行次数
  • 循环条件是k < 2*N,因此循环会执行2*N次;
  • 执行次数和输入规模N成正比,时间复杂度为O(N)(忽略系数 2,因为系数不影响量级)。
(2)while 循环的执行次数
  • M初始值为 10,每次循环M--,直到M=0,共执行10 次
  • 10 是固定常数,和N无关,时间复杂度为O(1)
(3)其他操作
  • int count = 0int M = 10System.out.println(count)都是单次执行的常数操作,时间复杂度为 O (1)。

整体时间复杂度推导::

根据时间复杂度的「加法规则」(多个操作的时间复杂度取最高量级):总时间复杂度 = O (2N) + O (1) = O (N) + O (1) =O(N)

// 计算func3的时间复杂度? void func3(int N, int M) { int count = 0; for (int k = 0; k < M; k++) { count++; } for (int k = 0; k < N ; k++) { count++; } System.out.println(count); }
(1)第一个 for 循环

循环条件是k < M,因此执行M 次,执行次数和输入规模 M 成正比,时间复杂度为O(M)

(2)第二个 for 循环

循环条件是k < N,因此执行N 次,执行次数和输入规模 N 成正比,时间复杂度为O(N)

(3)其他操作

int count = 0System.out.println(count)都是单次执行的常数操作,时间复杂度为 O (1),可忽略。

整体时间复杂度推导

根据时间复杂度的「加法规则」(多个串行操作的复杂度取各操作复杂度之和,保留核心量级):总时间复杂度 = O (M) + O (N) + O (1) =O(M + N)

(如果题目隐含 M 和 N 属于同一量级(比如 M≈N),也可简化为 O (N))

// 计算func4的时间复杂度? void func4(int N) { int count = 0; for (int k = 0; k < 100; k++) { count++; } System.out.println(count); }
(1)for 循环的执行次数

循环条件是k < 100,因此循环体固定执行 100 次—— 无论输入参数N取任何值(比如 N=1、N=1000、N=10^6),这个循环的执行次数都不会变,和N完全无关。

(2)其他操作

int count = 0System.out.println(count)都是单次执行的操作,属于常数级(O (1)),不影响整体复杂度。

整体时间复杂度推导

时间复杂度关注的是 “执行次数随输入规模N的增长趋势”:

  • 本题中,所有操作的执行次数(100 次循环 + 2 次单次操作)是固定常数,和N没有任何关联;
  • 根据时间复杂度的规则,常数次操作的时间复杂度统一记为O(1)(忽略具体的常数数值,比如 100、1000 都归为 O (1))。

(固定常数都是O(1))

// 计算bubbleSort的时间复杂度? void bubbleSort(int[] array) { for (int end = array.length; end > 0; end--) { boolean sorted = true; for (int i = 1; i < end; i++) { if (array[i - 1] > array[i]) { Swap(array, i - 1, i); sorted = false; } } if (sorted == true) { break; } } }

分场景推导时间复杂度(n = array.length)

场景 1:最坏情况(数组完全逆序,无提前退出)
  • 外层循环执行次数:n 轮(end 从 n → n-1 → ... → 1);
  • 内层循环执行次数:
    • 第 1 轮:i < n → 执行 n-1 次;
    • 第 2 轮:i < n-1 → 执行 n-2 次;
    • ...
    • 第 n-1 轮:i < 2 → 执行 1 次;
  • 总执行次数:(n-1) + (n-2) + ... + 1 = n (n-1)/2;
  • 时间复杂度:忽略常数和低次项,记为O(n²)
场景 2:最好情况(数组已有序,提前退出)
  • 外层循环仅执行 1 轮:
    • 内层循环遍历 n-1 次,无任何交换,sorted保持 true;
    • 触发break,外层循环直接终止;
  • 总执行次数:n-1 次(线性次数);
  • 时间复杂度:O(n)
场景 3:平均情况(随机无序数组)
  • 对于随机排列的数组,冒泡排序的平均比较 / 交换次数仍为 n² 量级(提前终止的优化仅减少常数次操作,不改变量级);
  • 平均时间复杂度:O(n²)(这是工程中最常用的冒泡排序复杂度表述)。

关键补充(为什么平均复杂度还是 O (n²))

时间复杂度的 “量级” 由最高次项决定:

  • 即使引入提前终止,冒泡排序的核心逻辑仍是 “嵌套循环”(外层 + 内层);
  • 只有 “完全有序” 的极端场景才会降到 O (n),绝大多数场景下,内层循环仍需执行 O (n) 次,外层循环执行 O (n) 次,总量级为 O (n²)。
// 计算binarySearch的时间复杂度? int binarySearch(int[] array, int value) { int begin = 0; int end = array.length - 1; while (begin <= end) { int mid = begin + ((end-begin) / 2); if (array[mid] < value) begin = mid + 1; else if (array[mid] > value) end = mid - 1; else return mid; } return -1; }

推导最坏时间复杂度(O (logn))

最坏情况是 “目标值不在数组中” 或 “目标值在最后一次才找到”,此时需要循环到区间长度为 0。

步骤 1:定义变量
  • n = 数组长度(输入规模);
  • k = 循环执行次数(我们需要求 k 和 n 的关系)。
步骤 2:分析每轮循环的区间长度
循环轮次查找区间长度区间长度表达式
初始nn = n/2⁰
第 1 轮后n/2n/2¹
第 2 轮后n/4n/2²
.........
第 k 轮后n/2ᵏn/2ᵏ
步骤 3:确定循环终止条件

最坏情况下,循环终止时区间长度 ≤ 0,即:2kn​≤1变形得:2k≥n两边取以 2 为底的对数:k≥log2​n

步骤 4:确定时间复杂度

循环执行次数 k 约等于 log2​n,因此最坏时间复杂度为O(log₂n)(通常简写为 O (logn),忽略对数的底数)。

其他场景的时间复杂度

场景 1:最好情况(O (1))

目标值恰好是数组的中间元素(第一次循环就命中),循环仅执行 1 次,时间复杂度为 O (1)。

场景 2:平均情况(O (logn))

对于随机分布的目标值,二分查找的平均循环次数约为 log2​n−1,忽略常数后仍为 O (logn)。

// 计算阶乘递归factorial的时间复杂度? long factorial(int N) { return N < 2 ? N : factorial(N-1) * N; }

推导时间复杂度的核心:统计递归调用次数

时间复杂度的本质是 “执行基本操作的次数随输入规模 N 的增长趋势”,对于递归函数,核心是统计递归调用的次数

  • 输入 N=1:调用 1 次(直接返回);
  • 输入 N=2:调用 2 次(factorial (2) → factorial (1));
  • 输入 N=3:调用 3 次(factorial (3) → factorial (2) → factorial (1));
  • ...
  • 输入 N=k:调用 k 次(从 N 递归到 1,共 N 次调用);

可以看到:递归调用次数和输入规模 N 成正比,每次调用内的操作(判断条件、乘法、返回值)都是常数级 O (1),因此总时间复杂度 = 调用次数 × 单次操作复杂度 = N × O (1) =O(N)

3补充:递归的空间复杂度(易混点)

顺带提一下空间复杂度,帮助你完整理解:

  • 递归调用会占用调用栈空间,每调用一次就会创建一个栈帧;
  • 阶乘递归的调用栈深度 = 递归调用次数 = N;
  • 因此空间复杂度为O(N)(而非 O (1),这是新手容易忽略的点)。
// 计算斐波那契递归fibonacci的时间复杂度? int fibonacci(int N) { return N < 2 ? N : fibonacci(N-1)+fibonacci(N-2); }

fibonacci(5)为例,画出递归调用树:

plaintext

fib(5) / \ fib(4) fib(3) / \ / \ fib(3) fib(2) fib(2) fib(1) / \ / \ / \ fib(2)fib(1)fib(1)fib(0)fib(1)fib(0) / \ fib(1)fib(0)
统计每一层的调用次数:
递归层级调用节点数节点数表达式
第 0 层(根)12⁰ = 1
第 1 层22¹ = 2
第 2 层42² = 4
第 3 层82³ = 8(实际 fib (5) 到第 3 层只有 4 个节点,是因为终止条件提前结束)
.........
第 n-1 层2ⁿ⁻¹2ⁿ⁻¹
核心观察:
  • 递归树的最大高度N(从 N 到 0);
  • 每一层的调用次数最多为2^层级
  • 总调用次数 ≈ 2⁰ + 2¹ + 2² + ... + 2ⁿ⁻¹ = 2ⁿ - 1(等比数列求和)。

数学推导时间复杂度

等比数列求和公式:总调用次数忽略常数项-1,总调用次数的量级为2ⁿ;每次递归调用内的操作(判断条件、加法、返回值)都是 O (1),因此总时间复杂度 = 调用次数 × O (1) =O(2ⁿ)

总结:如果层数有规律就求和公式,不要硬算

三.空间复杂度

①空间复杂度是对一个算法在运行过程中临时占用存储空间大小的量度 。空间复杂度不是程序占用了多少bytes的空间,因为这个也没太大意义,所以空间复杂度算的是变量的个数。空间复杂度计算规则基本跟时间复杂度类似,也使用大O渐进表示法

// 计算bubbleSort的空间复杂度? void bubbleSort(int[] array) { for (int end = array.length; end > 0; end--) { boolean sorted = true; for (int i = 1; i < end; i++) { if (array[i - 1] > array[i]) { Swap(array, i - 1, i); sorted = false; } } if (sorted == true) { break; }

1. 先明确空间复杂度的计算规则

空间复杂度关注的是「算法执行过程中额外占用的存储空间」(不包含输入数据本身的空间),核心判断标准:

  • 若额外空间是固定常数(和输入规模n无关),则为 O (1);
  • 若额外空间随n增长(如辅助数组、递归栈),则为 O (n)、O (logn) 等。
统计额外空间:
变量 / 操作占用空间是否随 n 变化
end(外层循环)1 个 int
sorted(标记)1 个 boolean
i(内层循环)1 个 int
Swap 中的 temp1 个 int

所有额外空间的总量是固定常数(4 个基础类型变量),和数组长度n完全无关。

核心结论:这段冒泡排序的空间复杂度是O(1)

// 计算fibonacci的空间复杂度? int[] fibonacci(int n) { long[] fibArray = new long[n + 1]; fibArray[0] = 0; fibArray[1] = 1; for (int i = 2; i <= n ; i++) { fibArray[i] = fibArray[i - 1] + fibArray [i - 2]; } return fibArray;
统计额外空间:
变量 / 操作占用空间是否随 n 变化
end(外层循环)1 个 int
sorted(标记)1 个 boolean
i(内层循环)1 个 int
Swap 中的 temp1 个 int

所有额外空间的总量是固定常数(4 个基础类型变量),和数组长度n完全无关。

关键补充(易混点)

  • 误区 1:“数组array占用空间很大,为什么不算?”→ 空间复杂度统计的是「额外空间」,输入参数array是原始数据空间,不计入算法的空间复杂度;
  • 误区 2:“嵌套循环会不会增加空间?”→ 空间复杂度和 “循环嵌套” 无关,只和 “额外变量的数量” 有关 —— 哪怕是 10 层嵌套,只要只用固定变量,空间复杂度仍是 O (1);
  • 对比:若冒泡排序需要额外创建一个和原数组等长的辅助数组,空间复杂度才会变成 O (n),但标准冒泡排序都是原地实现。

总结

  1. 核心结论:这段冒泡排序的空间复杂度是O(1)
// 计算阶乘递归Factorial的空间复杂度? long factorial(int N) { return N < 2 ? N : factorial(N-1)*N; }

1. 先明确递归空间复杂度的核心规则

递归函数的空间复杂度主要看调用栈的深度(而非临时变量):

  • 每次递归调用都会在「调用栈」中创建一个「栈帧」(存储函数的参数、返回地址等);
  • 栈帧的数量 = 递归调用的深度,若深度和输入规模 N 成正比,则空间复杂度为 O (N);
  • 临时变量仅占用常数空间(O (1)),不影响核心量级。

2. 拆解递归调用栈的执行过程

factorial(5)为例,调用栈的变化如下:

plaintext

// 调用流程:factorial(5) → factorial(4) → factorial(3) → factorial(2) → factorial(1) 栈深度1:factorial(5) // 等待 factorial(4) 返回 栈深度2:factorial(4) // 等待 factorial(3) 返回 栈深度3:factorial(3) // 等待 factorial(2) 返回 栈深度4:factorial(2) // 等待 factorial(1) 返回 栈深度5:factorial(1) // 触发终止条件,返回 1 // 回溯:依次弹出栈帧,计算 1×2→2×3→6×4→24×5→120
核心观察:
  • 递归调用的最大栈深度= N(比如 N=5 时栈深度为 5,N=10 时栈深度为 10);
  • 每个栈帧仅占用常数级空间(存储参数 N、返回地址等);
  • 总栈空间 = 栈深度 × 单个栈帧空间 = N × O (1) =O(N)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/1214959.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【计算机毕业设计案例】基于springboot的农业无人机农田巡查系统的设计与实现(程序+文档+讲解+定制)

博主介绍&#xff1a;✌️码农一枚 &#xff0c;专注于大学生项目实战开发、讲解和毕业&#x1f6a2;文撰写修改等。全栈领域优质创作者&#xff0c;博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围&#xff1a;&am…

【计算机毕业设计案例】基于springboot的汽车养护web系统基于SpringBoot的汽车美容与保养网站系统(程序+文档+讲解+定制)

博主介绍&#xff1a;✌️码农一枚 &#xff0c;专注于大学生项目实战开发、讲解和毕业&#x1f6a2;文撰写修改等。全栈领域优质创作者&#xff0c;博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围&#xff1a;&am…

【计算机毕业设计案例】基于Springboot的社区老年人健康管理系统(程序+文档+讲解+定制)

博主介绍&#xff1a;✌️码农一枚 &#xff0c;专注于大学生项目实战开发、讲解和毕业&#x1f6a2;文撰写修改等。全栈领域优质创作者&#xff0c;博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围&#xff1a;&am…

【计算机毕业设计案例】基于springboot的私厨服务菜品定制平台的设计与实现(程序+文档+讲解+定制)

博主介绍&#xff1a;✌️码农一枚 &#xff0c;专注于大学生项目实战开发、讲解和毕业&#x1f6a2;文撰写修改等。全栈领域优质创作者&#xff0c;博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围&#xff1a;&am…

讲讲适合年轻人的牛仔裤推荐,这些款式超受欢迎

2026年消费市场年轻化趋势显著,兼具时尚感与品质感的牛仔裤已成为年轻人日常穿搭的核心单品。无论是彰显个性的破洞设计、贴合身材的版型剪裁,还是经久耐穿的面料工艺,优质牛仔裤供应商的产品实力直接决定消费者的穿…

2026年实力强的动保产品定制代工排行榜,绿亚生物科技名列前茅!

本榜单依托全维度市场调研与真实行业反馈,深度筛选出五家动保产品定制代工领域的标杆企业,为养殖户、养殖集团及品牌方提供客观参考,助力精准匹配适配的服务伙伴。 TOP1 推荐:绿亚生物科技有限公司 推荐指数:★★…

GEO搜索优化品牌公司哪家好,湖南竞网智赢口碑出众

本榜单依托全维度市场调研与真实行业口碑,深度筛选出五家标杆企业,为企业布局AI流量入口提供客观依据,助力精准匹配适配的GEO优化服务伙伴。 TOP1 推荐:湖南竞网智赢网络技术有限公司 推荐指数:★★★★★ | 口碑…

分析PVC塑胶地板专业制造商,排名情况如何?

随着建筑装饰行业对地面材料环保性、耐用性需求的提升,PVC塑胶地板凭借多场景适配的优势逐渐成为公共空间与家庭装修的热门选择,但市场上PVC塑胶地板实力供应商PVC塑胶地板专业制造商源头PVC塑胶地板厂家的概念混杂,…

2026年欧盟地区靠谱的PVC塑胶地板供应商排名,新凯琳榜上有名!

本榜单依托全维度市场调研与真实行业口碑,深度筛选出五家标杆PVC塑胶地板制造商,为医院、学校、养老院等场景的采购方提供客观依据,助力精准匹配适配的服务伙伴。 TOP1 推荐:临沂新凯琳地板材料有限公司 推荐指数:…

2026年电商AI客服行业应用白皮书:拼多多智能客服、文字生成视频AI、电商短视频AI、美团AI客服机器人、营销视频AI制作选择指南

2026年电商AI客服行业应用白皮书 - 深度定制与标准化解决方案的实践剖析根据艾瑞咨询《2026年中国电商AI客服行业研究报告》,2026年中国电商行业GMV达37.2万亿元,同比增长8.5%,而电商客服成本占比持续攀升至12%。同…

Java计算机毕设之基于SpringBoot+Vue+MySQL的汽车维修预约服务系统基于springboot的汽车养护web系统(完整前后端代码+说明文档+LW,调试定制等)

博主介绍&#xff1a;✌️码农一枚 &#xff0c;专注于大学生项目实战开发、讲解和毕业&#x1f6a2;文撰写修改等。全栈领域优质创作者&#xff0c;博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围&#xff1a;&am…

Java毕设项目:基于springboot的无人机销售系统的设计与实现(源码+文档,讲解、调试运行,定制等)

博主介绍&#xff1a;✌️码农一枚 &#xff0c;专注于大学生项目实战开发、讲解和毕业&#x1f6a2;文撰写修改等。全栈领域优质创作者&#xff0c;博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围&#xff1a;&am…

【毕业设计】基于springboot的无人机销售系统的设计与实现(源码+文档+远程调试,全bao定制等)

博主介绍&#xff1a;✌️码农一枚 &#xff0c;专注于大学生项目实战开发、讲解和毕业&#x1f6a2;文撰写修改等。全栈领域优质创作者&#xff0c;博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围&#xff1a;&am…

分析西安不锈钢水箱供应商公司介绍,哪家更靠谱?

随着不锈钢水箱在建筑供水、消防储水等领域的应用日益广泛,西安地区的用户对不锈钢水箱厂家的选择愈发谨慎,西安不锈钢水箱厂家客户评价如何西安不锈钢水箱供应商公司介绍西安不锈钢水箱厂家评价好吗成为高频搜索问题…

【课程设计/毕业设计】基于SpringBoot + Vue的智能汽车养护系统的设计与实现基于springboot的汽车养护web系统【附源码、数据库、万字文档】

博主介绍&#xff1a;✌️码农一枚 &#xff0c;专注于大学生项目实战开发、讲解和毕业&#x1f6a2;文撰写修改等。全栈领域优质创作者&#xff0c;博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围&#xff1a;&am…

2026年性价比高的艺体高考培训学校推荐,合肥东辰上榜了吗

2026年职业教育改革持续深化,艺体高考作为文化成绩中等生的升学捷径,已成为众多家庭突破教育分层的关键选择。然而,市场上艺体高考培训机构质量良莠不齐:部分机构缺乏系统课程体系,仅靠噱头吸引生源;部分机构重专…

2026年靠谱的GEO搜索优化公司盘点,Top10有哪些

2026年AI信息分发时代全面来临,GEO搜索优化已成为企业抢占AI流量入口、重塑品牌传播链路的核心战略。无论是通过AI平台自然植入品牌信息、实现低成本精准获客,还是压制竞品分流、构建长效流量引擎,专业GEO服务商的技…

运动橡胶地板服务商家怎么选择,新凯琳优势解读

在运动场地建设领域,一块优质的运动橡胶地板是保障运动安全、提升运动体验的核心基础,关乎场馆的运营效率与用户口碑。面对市场上琳琅满目的运动橡胶地板服务商家,如何找到既专业又可靠的供应商?以下结合产品特性、…

探寻抗菌PVC运动地板选购要点,新凯琳是好选择

2026年健康建材产业加速升级,抗菌PVC运动地板凭借耐用性、卫生性与定制化优势,成为医院、学校、养老机构等公共场景的核心地面材料选择。无论是抗菌性能的技术突破、场景化定制生产能力,还是全链路服务体系,优质专…

讲讲2026天津婚姻资质齐全律师团队,如何选择适合你的律所

在婚姻家事纠纷频发的当下,一个专业、有温度的律师团队是当事人守护权益的重要依托。面对市场上众多婚姻法律服务机构,如何找到真正能解决问题的专业力量?以下依据服务特色与专业能力,为你推荐5家的婚姻家事法律服…