C语言数据结构(1)复杂度(大o阶)

欢迎来到博主的专栏——C语言与数据结构
博主ID——代码小豪

文章目录

    • 如何判断代码的好坏
    • 时间复杂度
      • 什么是时间复杂度
      • 如何计算时间复杂度
    • 空间复杂度

如何判断代码的好坏

实现相同作用的不同代码,如何分辨这些代码的优劣之处呢?

有人说了,我写的代码10行,别人写的是20行,我的代码更加简洁。那就是好代码

在可读性方面可能会更优(简洁≠可读性高),但是一个软件的使用者是用户啊,用户不需要能够看明白你的代码,用户需要的是软件的使用体验。

因此判断一个算法的好与劣可以用运行时间来衡量。

那么如何得到一个程序的运行时间呢?最好的方法当然是运行测试一下。但是这样做的问题也就出现了。

我用一台00年的电脑,和一台24年电脑运行一段代码,当然是24年的电脑运行更快啦,甚至有可能是24年的电脑运行坏代码比00年的电脑运行好代码更快。那么难道能说运行快的代码比较好?

这种判断的方法明显受到了硬件层面的影响,程序员应该专注于程序,在程序方面来判断算法的优劣,于是时间复杂度和空间复杂的概念就出现了。

这两个概念是用来判断实现的代码的算法的优劣性的。

时间复杂度

代码的运行时间,和算法的执行次数是明显呈现正相关关系的。

比如那个写了10行的代码,但是循环了100多次。而那个写了20行的代码,只需要执行1次。那么很明显,后者的运行时间快于前者。

时间复杂度的判断也是基于此,通过计算算法的执行次数来估计程序的运行快慢

什么是时间复杂度

时间复杂度是一个数学函数,用来评估一个算法在n的输入规模下,与执行指令的次数的关系

以计算1~n的各个数之和为例。常见的算法有以下两种

int sum_of_nums(int n)
{int sum = 0;for (int i = 1; i < n; i++){sum += i;}return sum;
}

可以发现,当n为100时,这个算法执行的指令次数为202次

```c
int sum_of_nums(int n)
{int sum = 0;//1次for (int i = 1; i <= n; i++)//100次{sum += i;//100次}return sum;//1次
}

如果输入为n,那么这个算法执行的指令总次数为2n+2次。

高中数学学过等差数列的求和公式为

Sn=n*(a1+an)/2

而1~n的整数求和本质上也就是a1为1,an为n的等差数列求和,所以用这种算法写出来的代码如下

int sum_of_nums(int n)
{int sum = 0;sum = n * (1 + n) / 2;return sum;
}

这个算法无论输入N等于多少,指令的执行次数都是3次。

很明显后者的算法优于前者,并且随着n的增加,后者的优势会更加明显。

那么我们假设还有一种算法,其实现是这样的

int sum_of_nums(int n)
{int sum = 0;for (int i = 1; i <= n; i++){for (int j = 1; j <= i; j++){if (j == i)sum += j;}}return sum;
}

如果输入为n,这个算法执行的次数为(1+2+3+……+n)+2,即n/2+n^2/2+2.

将上述算法的指令执行次数和输入规模的关系画成一个函数关系图,图形如下:
在这里插入图片描述
(手绘图形,不会画曲线–+)

根据图形,算法一:f(N)=2N+2是一个线性函数,因此时间复杂度是O(N),也就是常说的线性阶

算法2 f(N)=3,可以看到图像是一个常数函数,因此时间复杂度为O(1),也就是常数阶。

算法3 f(N)=N/2+N^2/2+2 可以看到图像是一个指数函数,因此时间复杂度为O(N^2),即指数阶。

时间复杂度O(f(n))是用来评定算法的快慢的,大O阶实际上是一个估值。或者说是一个算法的评级,常见的复杂度有以下几种
(1)常数阶,O(1)
(2)线性阶,O(2)
(3)对数阶,O(logN) (二分查找就是典型的O(logN)的算法)
(4)指数阶,O(N^2)

看到这有人就觉得很疑惑了,比如我写的一个算法,运行指令和输入的关系函数f(n)=n,而别人的是f(n)=2n,但是为什么时间复杂度都是O(N)呢,明明我的程序更好啊,我不服。

实际上时间复杂度可以认为是一个算法的评级,比如考英语四级,我考了424,而别人考了100,虽然我的英语水平肯定高于100,但是英语的评级我们两个都是没过四级。

当然了,这种优化还是不错的,虽然没有将O(N)变成O(1),但是在运行速度当然会更快一步。

如何计算时间复杂度

时间复杂度的计算方式在上面就已经可以明显感觉到了。

即时间复杂度取决于输入与执行指令的关系函数的最高次数项。
比如f(N)=2N^2+22+3,那么这个算法的时间复杂度就是O(N^2),实际上也是很好理解的,如下图
在这里插入图片描述
对比可以发现,当n超过一定数量的时候, 只有次数高的项对指令的运行次数影响最大,其余项可以忽略不计。

计算大O阶的方法总结
(1)只保留最高次数项
(2)保留的最高次数项将系数改为1
(3)如果只有常数项,那么就是1.

空间复杂度

算法中除了运行的指令外,还有用来存储数据的内存空间也是需要考虑在内的,但是现代的计算机对于空间的需求已经不再那么抠抠索索了,甚至大部分的算法采取的思路都是“以空间换取时间”。

比如判断1~10000的水仙花数,除了使用大量的指令让其计算以外,也可以创造一个10000元素大小的数组,将已知的水仙花数对应下标的元素记为1,这样子就从计算水仙花数的问题,变为了检索数组元素的问题,时间缩减,但是空间上要多出10000个元素的空间占用。

空间复杂度的计算公式为S(n)=O(f(n)),f(n)为执行指令时,对内存占用空间的函数,比如递归的空间复杂度就是O(n),因为每次执行递归,都会在内存中多开辟一个空间。

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

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

相关文章

算法:A*算法最小实例

A*算法主要作用是寻找两个节点之间的最短路径 首先&#xff0c;需要定义一个表示地图的二维数组&#xff0c;其中0表示可通过的空地&#xff0c;1表示障碍物&#xff1a; const map [[0, 0, 0, 0, 0],[0, 1, 1, 0, 0],[0, 0, 0, 0, 0],[0, 1, 0, 1, 0],[0, 0, 0, 0, 0]];接着…

原子类-入门介绍和分类说明、基本类型原子类

Atomic翻译成中文是原子的意思。在化学上,我们知道原子是构成一般物质的最小单位,在化学 反应中是不可分割的。在我们这里Atomic是指一个操作是不可中断的。即使是在多个线程一起执 行的时候,一个操作一旦开始,就不会被其他线程干扰。 基本类型原子类 AtomicInteger:整…

在illustrator中按大小尺寸选择物体 <脚本 018>

在Illustrator中我们可以依据对象的属性 如:填充颜色、描边颜色或描边宽度来选择相同属性的对象,但是Illustrator中没有根据不同大小尺寸来选择对象的功能,下面介绍的就是根据大小尺寸选择对象的脚本。 1、下面是当前画板中的所有对象,我们想把一些在尺寸小一些的方形物体…

数据治理工程师 CDGA数据建模和设计

1. 以下选项不属于数据建模和设计治理中质量管理内容的是&#xff08;D &#xff09; A 开发数据建模和设计标准 B 评审数据模型以及数据库设计质量 C 管理数据模型版本与集成 D 评估数据模型运行效率 2. 关于实体的别名&#xff0c;以下对应关系不正确的是&#xff08;B &…

金融帝国实验室(Capitalism Lab)V10版本游戏平衡性优化与改进

即将推出的V10版本中的各种游戏平衡性优化与改进&#xff1a; ————————————— 一、当玩家被提议收购一家即将破产的公司时&#xff0c;显示商业秘密。 当一家公司濒临破产&#xff0c;玩家被提议收购该公司时&#xff0c;如果玩家有兴趣评估该公司&#xff0c;则无…

datavrap-各种各样的条形图(含详细操作步骤)

静态条形图&#xff1a;正确设置数据即可&#xff0c;导出的图形不会随着时间变化 最普通的静态条形图 黑色系风格的静态条形图 动态条形图&#xff1a;导出的图形会随着时间变化 普通的动态条形图 带数字滚动效果的动态条形图 简单的Top排行榜动态条形图 格式更丰富的Top排行榜…

联盛德-安全物联网芯片w800

联盛德-安全物联网芯片w800 前言一、w800简介&#xff1f;芯片外观 总结 前言 本文介绍w800的基本信息&#xff0c;详细规格&#xff0c;后续有时间会介绍如何适配openharmony的过程。 一、w800简介&#xff1f; W800 芯片是一款安全 IoT Wi-Fi/蓝牙 双模 SoC 芯片。支持 2.…

系统设计面试

如何处理一个系统设计的面试题 系统设计面试是一个开放式的对话。他们希望你去主导这个对话 第一步&#xff1a;描述使用场景&#xff0c;约束和假设 把所有需要的东西聚集在一起&#xff0c;审视问题。不停的提问&#xff0c;以至于我们可以明确使用场景和约束。讨论假设。 …

B语言 :我心目中永远的两位神共同开发出来的语言

B是贝尔实验室大约在1969年由Ken Thompson和Dennis Ritchie开发的一种编程语言。 B源于BCPL&#xff0c;它的名字可能是BCPL的缩写。汤普森的同事丹尼斯里奇推测&#xff0c;这个名字可能是基于Bon&#xff0c;这是汤普森为Multics设计的一种更早但与之无关的编程语言。[注1] …

lombok 相关注解

话不多说&#xff0c;lombok相关的注解的使用&#xff0c;需要添加入如下依赖&#xff1a; <dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.20</version> <!-- Spring Boot 项…

Vue-Router 路径匹配与重定向

一、效果与描述 通过设置路由匹配同时设置重定向&#xff0c;让输错的网址重定向到指定页面&#xff0c;例如在网页输入网页地址把路径进行任意修改&#xff0c;重定向到登录页面。 二、Vue-Router代码 import { createRouter, createWebHashHistory } from vue-routerimport …

代码随想录算法训练营第一天 | 704-二分法查找、27. 移除元素

数组基础 1、数组定义&#xff1a;数组是存放在连续内存空间上的相同类型数据的集合。 特点&#xff1a; 数组下标都是从0开始的。数组内存空间的地址是连续的 2、数组的元素是不能删的&#xff0c;只能覆盖。 704. 二分查找 1、题目链接&#xff1a;. - 力扣&#xff08…

2024年华为OD机试真题-小明找位置-Java-OD统一考试(C卷)

题目描述&#xff1a; 小朋友出操&#xff0c;按学号从小到大排成一列&#xff1b;小明来迟了&#xff0c;请你给小明出个主意&#xff0c;让他尽快找到他应该排的位置。 算法复杂度要求不高于nLog(n)&#xff1b;学号为整数类型&#xff0c;队列规模<10000&#xff1b; 输入…

vue 中import 不同层级目录下的文件的表示方式

项目场景&#xff1a; 项目背景&#xff1a; vue 项目中开发页面 需要 用到其它目录下的 文件&#xff0c;需要使用 import 进行导入 问题描述 问题&#xff1a; import util from /libs/util.jsimport drawer from ../drawer/drawerimport mixinViewModule from /mixins/vi…

vue3+ts+vite中封装axios,使用方法从0到1

一、安装axios npm install axios types/axios --save二、配置代理vite.config.ts&#xff0c;如果没有需要新建该文件 module.exports {server: {proxy: {/api: {target: http://localhost:5000, // 设置代理目标changeOrigin: true, // 是否改变请求源地址rewrite: (path)…

氢原子为什么没有中子呢?

问题描述&#xff1a;氢原子为什么没有中子呢&#xff1f; 问题解答&#xff1a; 氢原子是唯一一个没有中子的常见原子。其原子核只包含一个质子&#xff0c;而中子的质量与质子相当&#xff0c;但没有电荷。氢原子的构成为一个质子和一个电子&#xff0c;因此没有中子。 原…

ECMAScript 6 (二)

ECMAScript 6 (二) 面向对象的扩展 不可扩展 一级保护&#xff0c;不可扩展 我们之前在创建的时候&#xff0c;因为JS是一个弱语言&#xff0c;所以对象在创建好之后&#xff0c;任然可以二次添加删除修改属性 同时在ES6里面&#xff0c;虽然推出了const&#xff0c;但是con…

pom.xml中resouces标签

pom.xml中resouces标签 resources是maven在编译项目时将资源文件或者额外的文件赋值到输出目录(target/classes)中。通常包括配置文件&#xff0c;属性文件&#xff0c;模板文件&#xff0c;jar包等。 resouces中可以包含resouce。也就是可以自定义的配置多个资源配置。 direct…

数据结构学习之单向循环链表应用的案例(旋转链表)

实例要求&#xff1a; 1、给定一个链表的头节点 head &#xff0c;请你旋转链表&#xff0c;将链表每个节点向右移动 k 个位置&#xff1b; 2、链表中节点的数目的范围为[0, 500] &#xff1b; 实例分析&#xff1a; 1、入参合理性检查&#xff0c;即head ! NULL || head-&…