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,一经查实,立即删除!

相关文章

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

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

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

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

金融帝国实验室(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.…

Vue-Router 路径匹配与重定向

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

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

JVM运行时数据区(下篇)

紧接上篇&#xff1a;JVM运行时数据区&#xff08;上篇&#xff09;-CSDN博客 堆 一般Java程序中堆内存是空间最大的一块内存区域。创建出来的对象都存在于堆上。 栈上的局部变量表中&#xff0c;可以存放堆上对象的引用。静态变量也可以存放堆对象的引用&#xff0c;通过静态…

Word插件-大珩助手-手写电子签名

手写签名 支持鼠标写&#xff0c;支持触摸屏写&#xff0c;点击画笔按钮切换橡皮擦&#xff0c;支持清空画板重写&#xff0c;点击在word中插入签名&#xff0c;可插入背景透明的签字图 素材库-保存签名 将写好的签字图复制粘贴到素材库中&#xff0c;以便永久使用&#xff…

AMEYA360:广和通RedCap模组FG131FG132系列

2024年1月&#xff0c;广和通RedCap模组FG131&FG132系列已进入工程送样阶段&#xff0c;可为终端客户提供样片。广和通RedCap模组系列满足不同终端对5G速率、功耗、尺寸、成本的需求&#xff0c;全面助力RedCap技术的行业应用。 FG131&FG132系列基于骁龙X35 5G调制解调…

第六站:C++面向对象

面向对象的第一概念:类 类的构成: “类”&#xff0c;是一种特殊的“数据类型”&#xff0c;不是一个具体的数据。 类的设计: 创建一个类: class Human { public://公有的,对外的void eat();//方法,成员函数void sleep();void play();void work();string getName();//获取对内…

Git相关3 —— 命令及添加Gitee的公钥

1.Git相关命令1 -- 工作目录、暂存区、本地仓库、 使用平台有&#xff1a;cmd、Git bash、VSCode window系统修改VSCode默认终端为git bash git init 初始化 --- 新增.git 文件夹 git status 查看 文件/文件夹 状态 git add 需要追踪的文件名/文件夹名 提交到暂存区 git add…

Electron中 主进程(Main Process)与 渲染进程 (Renderer Process) 通信的方式

1. 渲染进程向主进程通信 修改 html 文件内容 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><!-- 解决控制…

Sublime Text4 crack时替换的汇编指令

Sublime Text4 crack时替换的汇编指令 首先请支持正版&#xff0c;这里研究破解的步骤&#xff0c;仅做汇编代码学习。 破解步骤很简单&#xff1a; 打开二进制文件&#xff0c; 搜索 80 78 05 00 0F 94 C1&#xff0c; 替换为 C6 40 05 01 48 85 C9. (源: https://gist.git…

项目成本管理

4过程&#xff1a; 规划成本管理&#xff0c;估算成本&#xff0c;制定预算&#xff0c;控制成本 估算和预算的区别&#xff1a; 估算时准备向上级拿钱&#xff0c;通常是数值&#xff0c;项目团队做&#xff0c; 预算是拿到钱之后怎么花&#xff0c;通常是S曲线&#xff0c…

AI-数学-高中-4.函数表达式特性-要变一起变

原作者视频&#xff1a;函数】1引导课&#xff1a;高中为什么用f(x)_哔哩哔哩_bilibili 1.什么是函数&#xff1a;给定任意一个x&#xff0c;都有唯一确定的y与之对应&#xff0c;这种x与y的关系就叫函数&#xff0c;类似一个加工厂。 判断图像是否是函数&#xff0c;用竖直线…

如何用MetaGPT帮你写一个贪吃蛇的小游戏项目

如何用MetaGPT帮你写一个贪吃蛇的小游戏项目 MetaGPT是基于大型语言模型(LLMs)的多智能体写作框架&#xff0c;目前在Github开源&#xff0c;其Start数量也是比较高的&#xff0c;是一款非常不错的开源框架。 下面将带你进入MetaGPT的大门&#xff0c;开启MetaGPT的体验之旅。…

Flutter开发进阶之并发操作数据库

Flutter开发进阶之并发操作数据库 尽管 Flutter 本身不包含任何数据库功能&#xff0c;但可以使用各种第三方库和插件来在 Flutter 应用程序中实现数据库功能&#xff1b; 以下将使用sqflite作为例子&#xff0c;sqflite允许在 Flutter 应用程序中执行 SQL 查询&#xff0c;创…