数据结构与算法——4时间复杂度分析2(常见的大O阶)

news2024/9/22 11:32:04

这篇文章是时间复杂度分析的第二篇。在前一篇文章中,我们从0推导出了为什么要用时间复杂度,时间复杂度如何分析以及时间复杂度的表示三部分内容。这篇文章,是对一些常用的时间复杂度进行一个总结,相当于是一个小结论

1.常见的大O阶

1.1线性阶

一般含有非嵌套循环(就是单层循环)涉及线性阶,线性阶就是随着输入规模的扩大,对应计算次数呈直线增长,例如下面的代码:

public static void main(String[] args) {
        int sum = 0;
        int n = 100;
        for (int i = 1; i <=n ; i++) {
            sum += i;
        }
        System.out.println("sum="+sum);
    }

上面这段代码,它的循环的时间复杂度为O(n),因为循环体中的代码需要执行n次

1.2平方阶

一般嵌套循环(就是双层循环)属于这种时间复杂度

    public static void main(String[] args) {
        int sum = 0;
        int n = 100;
        for (int i = 1; i <=n ; i++) {
            for (int j = 1; j <=n ; j++) {
                sum += i;
            }
        }
        System.out.println("sum="+sum);
    }

上面这段代码,n=100,也就是说,外层循环每执行一次,内层循环就执行100次,那总共程序想要从这两个循环中出来,就需要执行100*100次,也就是n的平方次,所以这段代码的时间复杂度是O(n^2)

1.3立方阶

一般三层嵌套循环属于这种时间复杂度

public static void main(String[] args) {
        int x = 0;
        int n = 100;
        for (int i = 1; i <=n ; i++) {
            for (int j = 1; j <=n ; j++) {
                for (int k = 1; k <=n ; k++) {
                    x ++; 
                }
            }
        }
        System.out.println("x="+x);
    }

上面这段代码,n=100,也就是说,外层循环每执行一次,中间循环循环就执行100次,中间循环每执行一次,最内层循环需要执行100次,那总共程序想要从这三个循环中出来,就需要执行100*100*100次,也就是n的立方,所以这段代码的时间复杂度是O(n^3)

1.4对数阶

对数,属于高中数学的内容,我们分析程序以程序为主,数学为辅,所以不用过分担心。

    public static void main(String[] args) {
        int i = 0;
        int n = 100;
        while (i<n){
            i = i*2;
        }
        System.out.println("i="+i);
    }

分析:

由于每次i*2之后,就距离n更近一步。我们假设有x个2相乘后大于n,那么x个2相乘后就会退出循环。那么就有公式:2^x=n,得到x=log(2)n。所以这个循环的时间复杂度为O(logn);

问:为什么底数可以忽略?
答:对于对数阶,由于随着输入规模n的增大,不管底数为多少,他们的增长趋势是一样的,所以我们会忽略底数。(其实就是找输入规模n与执行次数之间的抽象关系,抓取主要的,忽略次要的)

下面给出表和图,可以体会一下增长趋势:

b6996b8058214bef8a86195f66ac1a7d.png

a8b32883c8a44aa78eeb2e347b4eb29b.png 

1.5常数阶

一般不涉及循环操作的都是常数阶,因为它不会随着n的增长而增加操作次数。例如︰

 public static void main(String[] args) {
        int n = 100;
        int i = n+2;
        System.out.println("i="+i);
    }

上述代码,不管输入规模n是多少,都执行2次,根据大O推导法则,常数用1来替换,所以上述代码的时间复杂度为O(1)

1.6小结

下面是对常见时间复杂度的一个总结:

835ad96cb4494ad58f1f1e1a4781f83a.png

他们的时间复杂度从高到低依次是:

                O(1)<O( log(n) )<O(n)<O(n*log(n))<O(n^2)<O(n^3) 

根据前面的折线图分析,我们会发现,从平方阶开始,随着输入规模的增大,时间成本会急剧增大,所以,我们的算法,尽可能的追求的是O(1),O(log(n)),O(n),O(n^log(n))这几种时间复杂度,而如果发现算法的时间复杂度为平方阶、立方阶或者更复杂的,那我们可以分为这种算法是不可取的,需要优化。

2.函数调用的时间复杂度分析

之前,我们分析的都是单个函数内,算法代码的时间复杂度,接下来我们分析函数调用过程中时间复杂度。

2.1几个案例

 案例一:

public static void main(String[] args) {
        int n = 100;
        for (int i = 0; i < n; i++) {
            show(i);
        }
    }
    public static void show(int i){
        System.out.println(i);
    }

在main方法中,有一个for循环,循环体调用了show方法,由于show方法内部只执行了一行代码,所以show的时间复杂度为O(1),那main方法的时间复杂度就是O(n)

案例二:

public static void main(String[] args) {
        int n = 100;
        for (int i = 0; i < n; i++) {
            show(i);
        }
    }
    public static void show(int i){
        for (int j = 0; j < i; j++) {
            System.out.println(i);
        }
    }

在main方法中,有一个for循环,循环体调用了show方法,由于show方法内部也有一个for循环,所以show方法的时间复杂度为O(n),那main方法的时间复杂度为O(n^2)

案例三:

public static void main(String[] args) {
        int n = 100;
        for (int i = 0; i < n; i++) {
            show(i);
        }
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < n; j++) {
                System.out.println(j);
            }
        }
    }
    public static void show(int i){
        for (int j = 0; j < i; j++) {
            System.out.println(i);
        }
    }

在show方法中,有一个for循环,所以show方法的时间复杂度为o(n),在main方法中,show(n)这行代码内部执行的次数为n,第一个for循环内调用了show方法,所以其执行次数为n^2,第二个嵌套for循环内只执行了一行代码,所以其执行次数为n^2,那么main方法总执行次数为n+n^2+n^2=2n^2+n。

根据大O推导规则,去掉n保留最高阶项,并去掉最高阶项的常数因子2,所以最终main方法的时间复杂度为O(n^2)


2.2最坏情况

从心理学角度讲,每个人对发生的事情都会有一个预期,比如看到半杯水,有人会说︰哇哦,还有半杯水哦!但也有人会说∶天哪,只有半杯水了。一般人处于一种对未来失败的担忧,而在预期的时候趋向做最坏的打算,这样即使最糟糕的结果出现,当事人也有了心理准备,比较容易接受结果。假如最糟糕的结果并没有出现,当事人会很快乐。
算法分析也是类似,假如有一个需求∶
                有一个存储了n个随机数字的数组,请从中查找出指定的数字。

public static void main(String[] args) {
        int a = search(5);
        System.out.println(a);
    }
    public static int search(int num){
        int[] arr = {11,5,3,6,7,15,6,9};
        for (int i = 0; i < arr.length; i++) {
            if (num == arr[i]) {
                return i;
            }
        }
        return -1;
    }

最好情况:
        查找的第一个数字就是期望的数字,那么算法的时间复杂度为O(1)

最坏情况:
        查找的最后一个数字,才是期望的数字,那么算法的时间复杂度为O(n)

平均情况:
        任何数字查找的平均成本是O(n/2)


最坏情况是一种保证,在应用中,这是一种最基本的保障,即使在最坏情况下,也能够正常提供服务,所以,除非特别指定,我们提到的运行时间都指的是最坏情况下的运行时间。

3.小结

这篇文章,我们总结了一些常见的大O阶,然后给出了相应的表格,这属于是一种结论,可以记下来的。然后我们分析了函数调用时的时间复杂度,其实和之前的分析方法是一样的。最后,我们讲了一下最坏情况的分析。

至此,算法的时间复杂度的讲解已经完毕了。如果有失误的地方,敬请各位指出,谢谢大家!

 

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

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

相关文章

ESFP型人格的特征,ESFP型人格的优势和劣势分析

ESFP型人格的特征ESFP&#xff08;表演者型人格&#xff09;是人群中的开心果。他们外向&#xff0c;友善&#xff0c;包容&#xff0c;有他们在的地方总是充满着活泼的氛围。ESFP对于新的朋友&#xff0c;新的环境适应良好&#xff0c;他们是完完全全的社交动物&#xff0c;对…

【数据库原理 | MySQL】一文打通 DDL语句

&#x1f935;‍♂️ 个人主页: 计算机魔术师 &#x1f468;‍&#x1f4bb; 作者简介&#xff1a;CSDN内容合伙人&#xff0c;全栈领域优质创作者。 书接上文介绍了数据库的前世今生&#xff0c;本文讲解SQL语句中的DDL语句 文章目录二、SQL2.1 SQL通用语法2.2 SQL的分类三、 …

I.MX6ULL_Linux_系统篇(19) kernel编译及Makefile分析

Linux 内核 Linux 由 Linux 基金会管理与发布&#xff0c; Linux 官网为 https://www.kernel.org&#xff0c;所以你想获取最新的Linux 版本就可以在这个网站上下载&#xff0c;网站界面如图所示&#xff1a; 从图中可以看出最新的稳定版 Linux 已经到了 6.2&#xff0c;NXP …

Python常用标准库-sys库一文详解

目录 前言 一、Sys库概述 二、Sys查看版本信息 1.sys.version获取Python版本信息 2.sys.api_version获取解释器中C的API版本 3.sys.getwindowsversion系统功能版本 4.sys.hexversion()获取Python解释器的版本值 5.sys.implementation获取当前正在运行的Python解释器的实现…

Redis源码---如何实现一个性能优异的Hash表

目录 前言 Redis 如何实现链式哈希&#xff1f; 什么是哈希冲突&#xff1f; 链式哈希如何设计与实现&#xff1f; Redis 如何实现 rehash&#xff1f; 什么时候触发 rehash&#xff1f; rehash 扩容扩多大&#xff1f; 渐进式 rehash 如何实现&#xff1f; 前言 Hash …

数据处理 |遍历所有文件夹及子目录文件夹方法总结与实例代码详解

深度学习中不可避免的数据预处理~1. glob.glob()方法 2. pathlib中的Path方法3. os.walk()方法1. glob.glob()方法 语法glob.glob(pathname)&#xff08;多指定文件类型&#xff0c;查找jpg,png,txt,json等&#xff09;缺点&#xff1a;查找文件较慢2. 路径操作库pathlib中的Pa…

【计算机三级网络技术】 第四篇 路由设计技术基础

文章目录一、分组转发二、路由选择1.理想的路由算法的基本特征2.路由算法的度量标准3.路由算法分类&#xff1a;4.IP路由选择与路由汇聚(重点)三、自治系统与Internet的路由选择协议1.自治系统2.路由选择协议的分类四、内部网关协议1.RIP的基本概念2.RIP的原理3.RIP的运行过程五…

Android Lmkd 低内存终止守护程序

一、低内存终止守护程序 Android 低内存终止守护程序 (lmkd) 进程可监控运行中的 Android 系统的内存状态&#xff0c;并通过终止最不必要的进程来应对内存压力大的问题&#xff0c;使系统以可接受的性能水平运行。 所有应用进程都是从zygote孵化出来的&#xff0c;记录在AMS…

Android问题笔记 - 打开Android Studio先弹出项目选择框

专栏分享点击跳转>Unity3D特效百例点击跳转>案例项目实战源码点击跳转>游戏脚本-辅助自动化点击跳转>Android控件全解手册点击跳转>Scratch编程案例 &#x1f449;关于作者 众所周知&#xff0c;人生是一个漫长的流程&#xff0c;不断克服困难&#xff0c;不断…

leetcode 427. Construct Quad Tree(构建四叉树)

刚看到题的时候是懵的&#xff0c;这也太长了。到底是要表达什么呢。 不妨把这个矩阵看成一个正方形的图片&#xff0c;想象你在处理图片&#xff0c;从整体逐步到局部。 刚开始看一整张图片&#xff0c;如果是全0或全1&#xff0c;这个就是叶子节点&#xff0c;怎么表达叶子节…

网络货运平台“降本提质引流增值”秘籍是什么?

2月24日&#xff0c;2022&#xff08;第五届&#xff09;中国网络货运平台年会在厦门举行&#xff0c;数据宝作为中物联副会长单位受邀参加峰会&#xff0c;数据宝轮值CEO肖斌发表题为“网络货运平台数字化创新应用实践分享”的主题分享。 据交通运输部统计&#xff0c;截止到2…

某建筑设计研究院“综合布线管理软件”应用实践

某建筑设计研究院有限公司&#xff08;简称“某院”&#xff09;隶属于国务院国资委直属的大型骨干科技型中央企业。“某院”前身为中央直属设计公司&#xff0c;创建于1952年。成立近70年来&#xff0c;始终秉承优良传统&#xff0c;致力于推进国内勘察设计产业的创新发展&…

CASENet中edge GT是如何产生的

1&#xff1a;首先下载cityscape数据集&#xff0c;包含两个大文件夹&#xff0c;具体的数据集介绍参考此链接。cityscape数据集解析 看一下gtFine子文件夹&#xff0c;另一个也是同理&#xff1a; 2&#xff1a;将下载好的数据集放到data_orig中&#xff0c;还有一个文件…

报错记录:element-admin框架打包后静态文件加载异常与登录异常解决方案

报错记录&#xff1a;element-admin框架打包后静态文件加载异常与登录异常解决方案 一、静态文件加载异常解决方案 二、登录异常解决方案 现象 element-admin如果用 electron 打包 是会有个问题&#xff1a; electron serve 运行没问题 electron build 打release 包 就会出错…

AST之path常用属性和方法总结笔记

文章目录1. path常用属性总结1.1 path.node1.2 path.scope1.3 path.parentPath1.4 path.parent1.5 path.container1.6 path.type1.7 path.key2. path常用方法总结2.1 path.toString2.2 path.replaceWith2.3 path.replaceWithMultiple2.4 path.remove2.5 path.insertBefore2.6 p…

TypeScript 常用知识

「 推荐一个学习 ts 基础的专栏&#xff0c;满满的干货&#xff1a;typeScript 」 1、为什么推荐使用 TypeScript 【】ts 是 js 的超集&#xff0c;包含 js 的所有元素 【】ts 通过对代码进行类型检查&#xff0c;可以帮助我们避免在编写 js 时经常遇到令人痛苦的错误 【】强…

第六节 方法

方法 方法是一种语法结构。 方法的作用&#xff1a; 1.提高代码的复用性 2.让程序逻辑更加清晰 方法定义的完整格式&#xff1a; 修饰符 返回值类型 方法名&#xff08;形参列表&#xff09;{ 方法体的代码&#xff08;需要执行的功能代码&#xff09; return 返回值&#xff…

Unity性能优化: 性能优化之内存篇

前言 本文和传统的内存优化不一样&#xff0c;不是讲如何降低内存占用&#xff0c;而是讲编程开发中要注意的内存问题以及一些内存技术的演变与原理。 对惹&#xff0c;这里有一个游戏开发交流小组&#xff0c;希望大家可以点击进来一起交流一下开发经验呀 1: Application进程…

maven项目无法解析插件

发现问题使用IDEA创建Maven项目时&#xff0c;报错无法解析插件 org.apache.maven.plugins:maven-clean-plugin这里使用的是IDEA捆绑的Maven插件解决方案查看Maven配置打开用户设置文件settings.xml&#xff0c;在其中加入如果该路径下没有此文件&#xff0c;可以自己创建一个。…

软件分析笔记02---Intermediate Representation

整体contents compiler &#xff08;source code ——> machine code&#xff09; non-trivial非平凡的 经过 语义分析->语法分析->类型检查等各种trivial的分析&#xff08;前端&#xff09;&#xff0c;生成中间代码IR->进行non-trivial的分析&#xff08;及静…