算法复杂度 O(n) 和 O(log n) 详解
算法复杂度 O(n) 和 O(log n) 详解基本概念算法复杂度是用来衡量算法执行效率的数学表示主要关注时间复杂度执行时间随输入规模增长的关系。O(n) - 线性时间复杂度含义算法的执行时间与输入规模n成正比关系输入规模增加一倍执行时间也大约增加一倍直观理解n 10 → 需要10次操作 n 100 → 需要100次操作 n 1000 → 需要1000次操作代码示例// O(n) 的典型例子遍历数组 public int findMax(int[] array) { int max array[0]; for (int i 1; i array.length; i) { // 循环n次 if (array[i] max) { max array[i]; } } return max; } // 另一个例子线性搜索 public boolean contains(int[] array, int target) { for (int num : array) { // 循环n次 if (num target) { return true; } } return false; }性能曲线时间 ↑ | / | / | / | / ---------→ 输入规模nO(log n) - 对数时间复杂度含义算法的执行时间与输入规模n的对数成正比输入规模指数级增长执行时间只线性增长O(log n) 通常指 log₂n二进制对数直观理解n 10 → 需要约3-4次操作 (log₂10 ≈ 3.32) n 100 → 需要约6-7次操作 (log₂100 ≈ 6.64) n 1000 → 需要约10次操作 (log₂1000 ≈ 9.97) n 1000000 → 需要约20次操作 (log₂1000000 ≈ 19.93)代码示例// O(log n) 的典型例子二分查找 public int binarySearch(int[] sortedArray, int target) { int left 0; int right sortedArray.length - 1; while (left right) { // 每次循环将搜索范围减半 int mid left (right - left) / 2; if (sortedArray[mid] target) { return mid; } else if (sortedArray[mid] target) { left mid 1; // 搜索右半部分 } else { right mid - 1; // 搜索左半部分 } } return -1; } // 另一个例子在二叉搜索树中查找 class TreeNode { int val; TreeNode left, right; } public TreeNode searchBST(TreeNode root, int target) { while (root ! null) { if (root.val target) { return root; } else if (target root.val) { root root.left; // 每次排除一半节点 } else { root root.right; } } return null; }性能曲线时间 ↑ | | ------ | / | / ---------→ 输入规模n (对数尺度)两者对比效率对比表输入规模nO(n) 操作次数O(log n) 操作次数效率差距1010~42.5倍100100~714倍1,0001,000~10100倍1,000,0001,000,000~2050,000倍实际场景对比// 假设有100万个元素的排序数组 int[] hugeArray new int[1_000_000]; // 已排序 // O(n) 线性搜索最坏需要100万次比较 long start System.nanoTime(); linearSearch(hugeArray, target); long linearTime System.nanoTime() - start; // O(log n) 二分查找最多需要20次比较 start System.nanoTime(); binarySearch(hugeArray, target); long binaryTime System.nanoTime() - start; System.out.println(O(n)时间: linearTime ns); System.out.println(O(log n)时间: binaryTime ns); System.out.println(效率提升: (linearTime / binaryTime) 倍);在HashMap红黑树中的应用回到之前的HashMap例子// 哈希冲突严重时 // JDK7: 使用链表 → O(n) 时间复杂度 // JDK8: 使用红黑树 → O(log n) 时间复杂度 // 假设某个桶中有1000个冲突元素 // 链表查找需要1000次比较 (O(n)) // 红黑树查找需要log₂(1000)≈10次比较 (O(log n))为什么这个优化很重要// 恶意攻击场景攻击者故意制造哈希碰撞 // 没有红黑树HashMap退化为链表性能急剧下降 // 有红黑树即使大量碰撞性能依然可接受 // 实际测试数据 // 10,000个冲突元素 // - 链表10,000次比较 // - 红黑树14次比较 (log₂10000 ≈ 13.3)常见复杂度等级从优到劣O(1)- 常数时间最优O(log n)- 对数时间优秀O(n)- 线性时间良好O(n log n)- 线性对数时间可接受O(n²)- 平方时间较差O(2ⁿ)- 指数时间极差总结核心要点✅O(n)执行时间与输入规模成正比适合小规模数据✅O(log n)执行时间增长远慢于输入规模增长适合大规模数据✅HashMap红黑树优化将最坏情况从O(n)提升到O(log n)显著提升性能实用建议处理大数据集时优先选择O(log n)算法小规模数据时O(n)算法可能更简单实用理解算法复杂度有助于写出更高效的代码public class AlgorithmComplexityDemo { // O(n) 的典型例子遍历数组 public static int findMax(int[] array) { int max array[0]; for (int i 1; i array.length; i) { // 循环n次 if (array[i] max) { max array[i]; } } return max; } // 另一个例子线性搜索 public static boolean contains(int[] array, int target) { for (int num : array) { // 循环n次 if (num target) { return true; } } return false; } // O(log n) 的典型例子二分查找 public static int binarySearch(int[] sortedArray, int target) { int left 0; int right sortedArray.length - 1; while (left right) { // 每次循环将搜索范围减半 int mid left (right - left) / 2; if (sortedArray[mid] target) { return mid; } else if (sortedArray[mid] target) { left mid 1; // 搜索右半部分 } else { right mid - 1; // 搜索左半部分 } } return -1; } // 另一个例子在二叉搜索树中查找 class TreeNode { int val; TreeNode left, right; } public TreeNode searchBST(TreeNode root, int target) { while (root ! null) { if (root.val target) { return root; } else if (target root.val) { root root.left; // 每次排除一半节点 } else { root root.right; } } return null; } public static void main(String[] args) { // test1(); mathLogTest(); } private static void mathLogTest() { // // 常用对数底数为10 // log₁₀100 2 // 因为 10² 100 // log₁₀1000 3 // 因为 10³ 1000 // log₁₀10 1 // 因为 10¹ 10 // //// 自然对数底数为e约等于2.718 // ln(e) 1 // 因为 e¹ e // //// 二进制对数底数为2计算机科学常用 // log₂8 3 // 因为 2³ 8 // log₂16 4 // 因为 2⁴ 16 // log₂1024 10 // 因为 2¹⁰ 1024 System.out.println(Math.log10(100));// 2.0 System.out.println(Math.log(4)/Math.log(2));// 2.0 // Math.log() 方法计算的是自然对数以 e 为底 System.out.println(Math.log(100)/Math.log(2));// 6.643856189774725 System.out.println(Math.log(4));// 1.3862943611198906 } private static void test1() { int n 10_000_000; int[] array new int[n]; for (int i 0; i n; i) { array[i] i; } long start System.nanoTime(); boolean contains contains(array, 580000); long end System.nanoTime(); long cost end - start; System.out.println(contains is: contains , Time used: cost); int i binarySearch(array, 580000); long end2 System.nanoTime(); long cost2 end2 - end; System.out.println(The index of 580000 is: i , Time used: cost2 , fast: (float) cost2 / cost); } }

相关新闻

基于大数据的城市交通数据可视化平台系统-附源码

基于大数据的城市交通数据可视化平台系统-附源码

前言针对现代城市交通数据繁杂、数据孤岛严重、拥堵研判滞后、调度效率低等痛点,本文设计一款基于大数据技术的城市交通数据可视化平台,助力智慧交通精细化管控。平台采用前后端分离架构,后端依托Python、Spark框架完成多源数据采集&#xff…

2026/10/11 4:53:25 阅读更多 →
Mac外接硬盘无法写入?一文讲透文件系统格式、NTFS与exFAT的选择

Mac外接硬盘无法写入?一文讲透文件系统格式、NTFS与exFAT的选择

很多人第一次把移动硬盘插到 Mac 上,会遇到两种特别抓狂的情况:一种是从 Windows 电脑拿过来的 NTFS 硬盘,插上之后所有文件都能看,但想删一个、拖一个进去,系统直接提示“磁盘是只读的”;还有一种更离谱&a…

2026/10/11 4:52:24 阅读更多 →
企业微信API开发:修改配置为什么需要重启服务?

企业微信API开发:修改配置为什么需要重启服务?

在企业微信自动化系统中,接口地址、消息模板、发送规则和业务开关通常需要根据实际情况调整。 如果每次修改配置都必须重新部署或重启服务,不仅操作麻烦,还可能影响正在执行的任务。 可以根据配置类型,设计适合的更新机制。 一…

2026/10/11 4:52:24 阅读更多 →

最新新闻

Claude Code解惑硬核玩法:树莓派上跑TaoToken统一API通道是什么体验?

Claude Code解惑硬核玩法:树莓派上跑TaoToken统一API通道是什么体验?

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/11 5:38:48 阅读更多 →
Java图书租借系统实战:从状态机设计到并发控制

Java图书租借系统实战:从状态机设计到并发控制

如果你正在筹备 Java 方向的毕业设计,图书租借系统很可能是你绕不开的一道经典题目。它没有电商系统那么庞杂,也没有纯管理系统那么枯燥,但刚好能把 Java 后端开发的核心环节都覆盖一遍:用户权限、业务状态流转、数据库事务、并发…

2026/10/11 5:38:48 阅读更多 →
用Cursor 1小时搭建带长期记忆的情感陪伴智能体:TaoToken统一Key接入实战

用Cursor 1小时搭建带长期记忆的情感陪伴智能体:TaoToken统一Key接入实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/11 5:38:48 阅读更多 →
什么是低代码应用开发?

什么是低代码应用开发?

低代码应用开发,究竟是什么意思?最容易理解的说法,是把开发软件时反复使用的功能,提前做成可以配置、组合的能力。开发者通过可视化工具定义数据、页面和流程,需要特殊功能时,再补充代码。但只记住“拖拖拽…

2026/10/11 5:38:48 阅读更多 →
Live-Canvas 实战:用 OpenClaw 把 A2UI 画布接进 Agent 工作流

Live-Canvas 实战:用 OpenClaw 把 A2UI 画布接进 Agent 工作流

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/11 5:38:48 阅读更多 →
AI生成3D城市模块编辑器真的可用吗?用6个节点验证放置、撤销与保存回读

AI生成3D城市模块编辑器真的可用吗?用6个节点验证放置、撤销与保存回读

透明建筑模块逐步拼成一座城市,很容易让人觉得城市编辑器已经成立。但对普通用户和独立开发者来说,真正需要验证的不是“建筑能不能出现”,而是能否稳定完成一条编辑闭环: 选择模块 → 预览与旋转 → 网格吸附 → 正式提交 → 撤…

2026/10/11 5:37:48 阅读更多 →

日新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/11 0:00:27 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/11 0:00:27 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/11 0:00:27 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/11 0:00:27 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/11 0:00:27 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/11 0:00:27 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/10 5:23:50 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/9 21:32:20 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/10 10:38:42 阅读更多 →