做网站是/企业培训计划方案
🌇个人主页:_麦麦_
📚今日名言:生命中曾经有过的所有灿烂,都终究需要用寂寞来偿还。——《百年孤独》
目录
一、前言
二、正文
1.算法效率
1.1如何衡量一个算法的好坏
1.2算法的复杂度
2. 时间复杂度
2.1时间复杂度的概念
2.3 常见时间复杂度计算举例
三、结语
一、前言
小伙伴们好呀,今天为大家带来的是算法的相关知识,主要围绕算法的效率和时间复杂度并伴有一定的题目练习,希望能够为读者们带来一定的收获。
二、正文
1.算法效率
1.1如何衡量一个算法的好坏
相信在座的小伙伴们一定见识了许多题目,也一定想出了相应的解决方案。不可否认的是,在面对同一道题目,同一个需求,不同的人也会写出不同的解决方案,那么到底如何如何评判这些解决方案的好坏呢?
有的小伙伴可能会说这还不简单嘛,之间看谁的算法跑的快,也就是依据时间效率的高低来评判算法的好坏。不过在实际中,由于算法的运行环境不同,例如在不同的设备上同一算法的时间效率都可能是不一样的,更遑论是不同的算法了。显然,用时间效率来衡量一个算法的好坏是不可能的,那么有什么更好的方法呢?
1.2算法的复杂度
算法在编写成可执行程序后,运行时需要耗费时间资源和空间(内存)资源。因此衡量一个算法的好坏主要是从时间和空间两个维度来衡量的,即时间复杂度和空间复杂度。
时间复杂度主要衡量一个算法的运行快慢,而空间复杂度主要衡量一个算法运行所需要的额外空间。在计算器发展的早起,计算机的存储容量很小,所以对空间复杂度很是在乎,但是经过计算机行业的迅速发展,计算机的存储容量已经达到了很高的程度。所以我们如今应经不需要特别关注一个算法的空间复杂度。
2. 时间复杂度
2.1时间复杂度的概念
时间复杂度的定义:在计算机科学中,算法的时间复杂度是一个函数,它定量描述了该算法的运行时间。一个算法执行所耗费的时间,从理论上是不能算出来的,只有把你的程序放在机器上跑起来,才能知道。但是我们需要每个算法都上机测试吗?是都可以上机测试,但是这很麻烦,所以才有了时间复杂度这个分析方式。一个算法所花费的时间与其中语句的执行次数成正比例,算法中的基本操作的执行次数,为算法的时间复杂度。
即:找到某条基本语句与问题规模N之间的数学表达式,就是算出来该算法的时间复杂度。
说了这么多,纸上得来终觉浅,下面给小伙伴们举一些计算时间复杂度的例子,帮助大家更好地理解时间复杂度这一概念。
//请计算一下Func1中++count语句总共执行了多少次?
void Func1(int N)
{int count = 0;for (int i = 0; i < N; ++i){for (int j = 0; j < N; ++j){++count;}}for (int k = 0; k < 2 * N; ++k){++count;}int M = 10;while (M--){++count;}printf("%d\n", count);
}
看过上面的代码,相信你们一定能够很轻易的算出Fun1执行的基本操作次数是一个关于N的函数:F(N)=N²+2N+10
●N=10 F(N)=130
●N=100 F(N)=10210
●N=1000 F(N)=1002010
注:实际中我们计算时间复杂度时,我们其实并不一定要计算精确的执行次数,而只需要大概执行次数,具体操作是怎样呢,接下来我们引入大O的渐进表达法
2.2大O的渐进表示法
大O符号:适用于描述函数渐进行为的数学符号
推导大O阶方法:
1.用常数1取代运行时间中所有的加法常数
2.在修改后的运行次数函数中,只保留最高阶项
3.如果最高阶项存在且不为1,则去除与这个项目相乘的常数,得到的结果就是大O阶
因此,在上面的例子中,采取大O的渐进表示法以后,Fun1的时间复杂度为:F(N²)
●N=10 F(N)=130
●N=100 F(N)=10210
●N=1000 F(N)=1002010
通过上面我们会发现大O的渐进表示法去掉了哪些对结果影响不大的项,简洁明了的表示出了执行次数。不过随着算法的深入,我们会发现有些算法的时间复杂度并不是唯一确定的,而是存在着最好、平均和最坏情况:
●最坏情况:任意输入规模的最大运行次数(上界)
●平均情况:任意输入规模的期望运行次数
●最好情况:任意输入闺蜜的最小运行次数(下界)
例如:在一个长度为N的数组中搜查一个数据x
●最坏情况:N次找到
●平均情况:N/2次找到
●最好情况:1次找到
在实际中一般关注的是算法的最坏运行情况,所以数组中搜索数据的时间复杂度为O(N)。
之所以以最坏情况来作为算法的时间复杂度,在这里其实是应用了信息学中的“预期管理”,就好比情人节那天,你要与你的男/女朋友约会,而约会时间可能是17点、18点、19点,那么相信大多数的人都会选择19点,如果刚刚好19点来就挺守时的嘛,如果早来,还可以提前准备,给他/她一些惊喜。相反,如果你将约定时间定位17点或者18点,一旦无法在约定时间前来,就是放鸽子了,可能会产生意料之外的各种特殊情况……
因此,采取最坏情况作为时间复杂度的算法跑起来只有惊喜和预期,不可能比预期更坏。
2.3 常见时间复杂度计算举例
●实例1
// 计算Func2的时间复杂度
void Func2(int N)
{int count = 0;for (int k = 0; k < 2 * N ; ++ k){++count;}int M = 10;while (M--){++count;}printf("%d\n", count);
}
通过计算,F(N)=2N+10,因此该算法的时间复杂度为O(N)
●实例2
// 计算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;}printf("%d\n", count);
}
通过计算,在一般情况下,也就是M和N均为未知数的情况下,F(N)=M+N,所以O(N)=M+N
注:如果题目中说M远大于N,那么O(N)=M
●实例3
// 计算Func4的时间复杂度
void Func4(int N)
{int count = 0;for (int k = 0; k < 100; ++ k){++count;}printf("%d\n", count);
}
通过计算我们发现无论N取何值,F(N)始终等于一个常数也就是 ,根据 大O阶方法的一条,用1来代表所有常数,也就是该时间复杂度为O(1)
●实例4
// 计算strchr的时间复杂度
const char * strchr ( const char * str, int character );
对库函数有过一定了解的同学一定知道“strchr”这个函数会依次对str指针+1,如果找到目的字符便会返回其指针,找不到便会返回空指针。而这里就会存在最好、最坏和平均情况,因此该函数的时间复杂度为O(N)
注:未指定未知数的情况下默认为N
●实例5
// 计算BubbleSort的时间复杂度
void BubbleSort(int* a, int n)
{assert(a);for (size_t end = n; end > 0; --end){for (size_t i = 1; i < end; ++i){if (a[i-1] > a[i]){Swap(&a[i-1], &a[i]);exchange = 1;}}}
}
最好情况:O(N)——无须排序
最坏情况:O(N²)——全部交换
相信最坏情况的时间复杂度大家应该可以很轻易的想出来,但是最坏情况可能就有些复杂了。我们都知道冒泡排序共有两个流程,一个是趟数,一个是每趟交换的次数。那么时间复杂度就是总的交换次数。在看过博主之前推文对冒泡排序的小伙伴应该十分了解在冒泡排序最坏的情况下中,首趟交换的次数是最多的,为元素个数减,即N-1,之后虽趟数的增加,每趟交换的次数以1的速度递减。那么总的趟数计算的话其实就是一个高中很简单的等差数列求和,即(首项+尾项)*项数/2,代入N-1,可得F(N)=N*(N-1)/2,所以O(N)=N²。
●实例6
// 计算BinarySearch的时间复杂度——二分查找
int BinarySearch(int* a, int n, int x)
{assert(a);int begin = 0;int end = n - 1;// [begin, end]:begin和end是左闭右闭区间,因此有=号while (begin <= end){int mid = begin + ((end - begin) >> 1);if (a[mid] < x)begin = mid + 1;else if (a[mid] > x)end = mid - 1;elsereturn mid;}return -1;
}
二分查找又称折半查找法,是一种通过中间值与目标值进行比较,进而对数值进行筛选,循环往复来查找目标值的方法。
最好情况下,也就是第一次就找到目标值,此时时间复杂度为O(1)
最坏情况下,就是将数组不断二分直至长度为1为止,此时可能找到目标值也可能没有目标值。因此F(N)=log以2为底的对数,大部分情况下简写为logN,所以O(N)=logN。
●实例7
// 计算阶乘递归Fac的时间复杂度
long long Fac(size_t N)
{if (0 == N)return 1;return Fac(N - 1) * N;
}
有时候,我们可能在脑海中无法形象的,一下子的得出时间复杂度,这时候就可以通过画图来帮助自己理清思路,进而得出时间复杂度。通过上图,我们可以发现在最坏的情况下基本操作进行了N次,时间复杂度为O(N)
● 实例8
// 计算斐波那契递归Fib的时间复杂度
long long Fib(size_t N)
{if(N < 3)return 1;return Fib(N-1) + Fib(N-2);
}
我们发现这其实是一个等比数列求和,虽然右边有一些数提前递归结束,但是随着N的增大,是可以忽略不计的。因此该时间复杂度为O(2^N)
三、结语
到此为止,关于算法的时间复杂度的学习就告一段落了。
关注我 _麦麦_分享更多干货:_麦麦_的博客_CSDN博客-领域博主
大家的「关注❤️ + 点赞👍 + 收藏⭐」就是我创作的最大动力!谢谢大家的支持,我们下期见!
相关文章:

数据结构——算法的时间复杂度
🌇个人主页:_麦麦_ 📚今日名言:生命中曾经有过的所有灿烂,都终究需要用寂寞来偿还。——《百年孤独》 目录 一、前言 二、正文 1.算法效率 1.1如何衡量一个算法的好坏 1.2算法的复杂度 2. 时间复杂度 2.1时间复杂度的…...

Go基础-类型
文章目录1 bool2 有符号整数3 无符号整数4 浮点数5 复数6 string7 关于类型转型1 bool bool类型有两个值,一个是true,一个是false。 测试 package mainimport "fmt"func main() {a : trueb : falsec : a && bd : a || bfmt.Println(a…...

良许翻天覆地的2022年
大家好,我是良许,新年快乐呀~ 在我女室友坚持不懈的努力之下,2022年的最后一天我终于被她传染了,阳了~ 此时的我,正顶着37多度的低烧写下这篇年终总结。 2022年,对于大多数人而言,封控是主旋…...

node+vue微信小程序的社区后勤报修系统
社区后勤报修系统小程序进行总体设计和详细设计。总体设计主要包括小程序功能设计、小程序总体结构设计、小程序数据结构设计和小程序安全设计等:详细设计主要包括社区后勤报修系统小程序数据库访问的实现,主要功能模块的具体实现,模块实现关键代码等。最后对社区后…...

WSL(Windows Subsystem for Linux)
一、WSL优势 •传统方式:获取Linux操作系统环境,必须安装完整的虚拟机,如VMware•WSL:以非常轻量化的方式,得到Linux系统环境总结:WSL更方便,简单、好用、轻量化、省内存 二、什么是WSL ①不…...

华为OD机试题 - 单词反转(JavaScript)
最近更新的博客 华为OD机试题 - 任务总执行时长(JavaScript) 华为OD机试题 - 开放日活动(JavaScript) 华为OD机试 - 最近的点 | 备考思路,刷题要点,答疑 【新解法】 华为OD机试题 - 最小步骤数(JavaScript) 华为OD机试题 - 任务混部(JavaScript) 华为OD机试题 - N 进…...

人工智能原理复习 | 产生式系统的搜索策略
文章目录 一、回溯策略二、图搜索策略三、A 算法与 A* 算法CSDN 叶庭云:https://yetingyun.blog.csdn.net/ 主要内容:回溯策略、图搜索策略(无信息的图搜索、启发式的图搜索)、A 算法与 A* 算法 一、回溯策略 回溯算法(BackTracking Algorithm) 实际上是一个类似枚举的搜…...

初始C语言 - 数组(一维数组、二维数组、数组越界、数组传参)
目录 一、一维数组的创建和初始化 1、数组的创建 2、 数组的初始化 3.一维数组的使用 数组通过下标来访问 总结: 1. 数组是使用下标来访问的,下标是从0开始。 2. 数组的大小可以通过计算得到。 4、一维数组在内存中的存储 二、 二维数组的创建和初始化 1.二…...

人工智能原理复习 | 可分解产生式系统的搜索策略
文章目录 一、前言二、基础知识三、AO* 算法四、博弈树搜索五、总结CSDN 叶庭云:https://yetingyun.blog.csdn.net/ 主要内容: 与 / {/} /或图搜索、AO* 算法、极大极小过程、...

线段树(维护区间信息)
一,定义: 可以在logN时间内实现区间修改,单点修改,区间查询等操作的工具 二,思路(修改无乘法时): 1,建树 通过把区间不断二分建立一颗二叉树 我们以维护一个数组a{1…...

C语言 基于Ncurse库的贪吃蛇游戏项目
为了敲键盘及时响应,需要用到ncurse 测试代码: ncurse1.c /* ncurse1.c */ #include <curses.h> //ncurse的头文件。int main() {char c;int i 0;//ncurse界面的初始化函数。initscr(); for(i0;i<2;i){c getch();printw("\n");//…...

【Java基础】Java语言特性
认识Java java语言的执行过程 编写纯文本文件 .java 经过javac编译器(java complier)编译 .class .class是二进制的字节码 在源文件中定义几个类,就会生成几个 由JVM运行 .class JVM把字节码编译成可以在处理器上运行的高性能的本地代码(native code),…...

python进阶--Numyp库(一)
一、Numpy库介绍 NumPy(Numerical Python)是Python的⼀种开源的数值计算扩展。提供多维数组对象,各种派⽣对象(如掩码数组和矩阵),这种⼯具可⽤来存储和处理⼤型矩阵,⽐Python⾃身的嵌套列表&am…...

CV学习笔记-Inception
CV学习笔记-Inception 目录 文章目录CV学习笔记-Inception目录1. 常见的卷积神经网络2. Inception(1) Inception提出背景(2) Inception module 核心思想3. Inception的历史版本(1) InceptionV1-GoogleNet(2) InceptionV2(3) InceptionV3(4) Inception V44. Inception模型的特点…...

注意力机制笔记——结合沐神和B站老弓up主
B站【大白话浅谈【注意力机制】】 聚类 是针对 样本, 注意力机制是针对样本相关性,来进行计算的 自注意力机制 指的是 query ,key,value都是同一个部分。 可以学到 类似的 短语 ,和 语义特征。如its 指代的对象。 评论区大佬 根据这篇论文《Effective Approaches to…...

建议收藏,轻松搞懂区块链
未来已来,只是不均衡地分布在当下 大家好,我是菜农,欢迎来到我的频道。 本文共 5844字,预计阅读 30 分钟 区块链是近些年来最热门的前沿技术,被认为是未来十几年对金融、物联网、医疗等诸多领域产生最大影响的"…...

php设计一个新春祝福墙
记得十几年前的时候,每到春节,各大网站都会建一个祝福墙,上面挂满网友的新年寄语。这些年随着移动互联网的高速发展,web的新春祝福墙越来越少了。今天,咱们就来考考古,用快速原型法进行设计。原型设计采用M…...

KubeSphere 社区双周报 | OpenFunction 集成 WasmEdge | 2023.02.03-02.16
KubeSphere 社区双周报主要整理展示新增的贡献者名单和证书、新增的讲师证书以及两周内提交过 commit 的贡献者,并对近期重要的 PR 进行解析,同时还包含了线上/线下活动和布道推广等一系列社区动态。 本次双周报涵盖时间为:2023.02.03-2023.…...

数字IC/FPGA 秋招知识点不全面整理
1. 引言 这篇文章的由来 秋招的时候,刚开始复习一些知识点的时候没有什么思路,只是盲目的看相关的书籍和资料,结果是留在脑子中的知识很有限,而且不够系统,在我需要它的时候,并不能很快的回忆起来。 于是就想着把一些典型的知识整理成一个文档,在进行刷题的时候可以比…...

你知道java8是如何排序Map嘛?
在Java中,有多种方法可以对Map进行排序,但是我们将重点介绍Java 8 Stream,这是实现目标的一种非常优雅的方法。 学习一下HashMap的merge()函数 在学习Map排序之前,有必要讲一下HashMap的merge()函数,该函数应用场景就…...

【李忍考研传】一、李忍
“老师,我来回答!” “非常好,我记得你是叫……呃……是李念同学吗?” “不,老师,我叫李忍。” “好,你来回答一下这个问题。” “这题用海明码校验的知识,能检错一位纠错一位&a…...

测牛学堂:软件测试python深入之类和对象的属性和方法总结
类对象和实例对象 类对象就是我们定义的类。 在代码执行的时候,解释器会自动创建类对象。 类对象的作用: 1 使用类对象创建实例对象 2 存储类的一些特性,就是类里面定义的属性 创建对象的过程也称为实例化的对象。所以,类创建的对…...

css实例--新闻页面
实现效果 实现代码 html代码: <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge"><meta name"viewport" co…...

SpringCloudGateway 动态转发后端服务
API网关的核心功能是统一流量入口,实现路由转发,SpringCloudGateway是API网关开发的技术之一,此外比较流行的还有Kong和ApiSix,这2个都是基于OpenResty技术栈。 简单的路由转发可以通过SpringCloudGateway的配置文件实现…...

使用canvas写一个flappy bird小游戏
简介 canvas 是HTML5 提供的一种新标签,它可以支持 JavaScript 在上面绘画,控制每一个像素,它经常被用来制作小游戏,接下来我将用它来模仿制作一款叫flappy bird的小游戏。flappy bird(中文名:笨鸟先飞&am…...

KVM-2、虚拟化基础
1. 虚拟化概念 什么是虚拟化 **虚拟化是使用所谓虚拟机管理程序从一台物理机上创建若干个虚拟机的过程。**虚拟机的行为和运转方式与物理机一样,但它们会使用物理机的计算资源,如 CPU 、内存和存储。虚拟机管理程序会根据需要将这些计算资源分配给每个虚拟机。 虚拟化有哪…...

设计模式之观察者模式与访问者模式详解和应用
目录1.访问者模式详解1.1 访问者模式的定义1.1.1 访问者模式在生活中的体现1.1.2 访问者模式的适用场景1.2 访问者模式的通用实现1.3 访问者模式的使用案例之KPI考核1.3.1 类图设计1.3.2 代码实现1.4 访问者模式扩展---分派1.4.1 java中静态分派示例代码1.4.2 java中动态分派1.…...

spring注解方式整合Dubbo源码解析
系列文章目录 前言 本节我们的Dubbo源码版本基于2.6.x 在前一章我们的整合案例中,我们有几个比较关键的步骤: 在启动类上标注了EnableDubbo注解在provider类上面标注了Service注解来提供dubbo服务在消费的时候通过Reference注解引入dubbo服务在配置文件…...

大数值金额大写转换(C语言)
关于大数值金额大写转换,在财务管理的应用方面没什么意义。一般来说,千亿级,万亿级的数值就够了。因为在国家级层面是以亿为单位的,也就表达为千万亿,万万亿。在企业层面数值金额转换设置到千亿、万亿就行了。大的集团…...