衡量算法效率的方法:时间复杂度、空间复杂度

衡量算法效率的方法:时间复杂度、空间复杂度

  • 一、好算法的特点
  • 二、算法效率分析
    • 1. 时间复杂度
    • 2. 空间复杂度

一、好算法的特点

算法是用数学解决问题的方法。一个好算法有以下几个特点:
①正确性:能正确处理各种输入(合法输入、非法输入、边界输入),输出合理的结果。
②可读性:算法描述清晰,方便阅读、理解。
③健壮性:算法应运行一致,对于相同的输入始终输出相同的结果。
④高效性:算法应占用最少的CPU和内存,这一点通过时间复杂度和空间复杂度进行判定。
其中,高效性是优秀算法最突出的特点,也是算法设计的核心。

二、算法效率分析

算法的效率是用算法复杂度来衡量的,有两个方面:

  • 时间效率:算法运行有多快。
  • 空间效率:内存占用有多少。

1. 时间复杂度

算法的运行时间与编程语言、机器配置、机器的状态、数据量的大小都有关系,单纯比较运行时间并不能准备地衡量出算法效率。所以,应该找到一项时间效率的评判标准,只与算法本身有关,而与刚刚提到的那些臭氧层子无关。
由此,提出了时间复杂度的概念,简单来说,就是算法在运行时间层面的复杂程度。什么东西最能直接地体现出算法复不复杂呢?
我们知道,程序=指令+数据,指令就是命令,它是算法的核心。显然指令的数量越多,算法越复杂。我们可以用函数来表示指令的多少。
(1)大T函数T(n)
当只考虑问题规模(要处理的数据量的多少)时,指令执行的次数会随着问题规模的增大而增加,那么指令执行次数相对于问题规模来说,会构成一个函数T(n)。
例如,对于以下数组求和的算法1+2+3+…+n:

int sum = 0;    //指令数为1
for(int i=0; i<n; i++)sum += n;   //指令数为n
cout << n;        //指令数为1

显然,总的指令数为T(n)=n+2。
虽然这种计算效率的方法准确度很高,但是太复杂了,对平时的算法效率分析来讲,这样做不仅费时费力,而且完全没有必要。
(2):大O函数O(n)
大O函数是时间复杂度的一种估算方法。具体来说,它计算的是指令数量的级别,而不是准确的指令数量。就像开车一样,大T函数相当于计算车的速度,而大O函数相当于计算车的档位,显然后者要简单的多。
比如某算法的T(n)=9n3+5n+2。对于整个团队T(n)的贡献,最大的主力是最高次数的n3。当n越来越大时,其他项基本可以被忽略。
例如:当n=100时,n3是n的1万倍,因此可忽略5n的贡献。
当n从100变成1000时,n3会增长1000倍,此时9n3前面的系数9也不够看了,可被忽略。
我们常把这个主力单独拎出来衡量时间复杂度,用大O函数表示。前面的T(n)简化为O(T(n))=O(n3)。
大O函数的数学定义:存在正常数c和某个规模n0,如果对所有的n≥n0,都有f(n)≤cT(n),则称f(n)为T(n)的大O函数,写成f(n)=O(T(n))。
计算方法:对算法(或代码)的指令次数进行计算组成T(n),只保留最高次项,并去掉最高次项前面的常数。
(3):常见大O函数
常见大O函数的按时间由少到多排序如下:
在这里插入图片描述

代码示例:
O(n) 的例子:输出数组元素。

for(int i=0; i<n; i++)cout << a[n] << " ";

O(log n) 的例子:给定n,求p,使得p≤n<2p。
log n是 log ⁡ 2 n \log_2{n} log2n的简写,即以2为底n的对数。

int p = 1;
while(p < n) {p *= 2;
}
cout << p;

O(n2) 的例子:典型的就是二重循环,如打印二维数组。

for(int i=0; i<n; i++) {for(int j=0; j<n; j++)cout << a[i][j] << " ";cout << endl;
}

O(nlog n) 的例子:最典型的例子是快速排序,但这个例子比较复杂,这里只搞一个简明阉割版示意一下。

for(int i=0; i<n; i++) //第一重循环,复杂度O(n)for(int j=0; j<n; j *= 2) //第二重循环,复杂度O(log n)...

O(2n) 的例子:汉诺塔问题。
递归表达式如下:
1)将n-1个盘子从A经过C移动到B。
2)将第n个盘子从A移动到C。
3)将n-1个盘子从B经过A移动到C。
显然T(n)=2T(n-1)+1=2(2T(n-2)+1)+1=…,最高阶项为2n,即O(2n)。
O(n!) 的例子:旅行商问题,即从一个城市出发,经过所有城市后返回出发地,求最短的路径。
第一个城市有n种选择,第二个有n-1种选择,以此类推,复杂度为O(n!)。

2. 空间复杂度

空间复杂度是对一个算法在运行过程中占用内存空间大小的度量。
一个算法在计算机存储器上所占用的存储空间包括:
①代码本身占用空间。
②输入输出数据占用空间。
③过程占用空间。即程运行过程中临时占用的存储空间。
第②项取决于问题要求,不能改变;第①项取决于代码长度,影响也不大。

算法的输入输出数据所占用的存储空间是由要解决的问题决定的,它不随算法的不同而改变。
算法在运行过程中临时占用的存储空间因算法的不同而异,有的算法只需要占用少量的临时工作单元,而且不随问题规模的大小而改变,我们称这种算法是“就地”进行的,是节省存储空间的算法;有的算法需要占用的临时工作单元数与解决问题的规模n有关,它随着n的增大而增大,当n较大时,将占用较多的存储单元,如归并排序。
分析一个算法所占用的存储空间要从各方面综合考虑。如对于递归算法来说,一般都比较简短,算法本身所占用的存储空间较少,但运行时需要一个附加栈,从而占用较多的临时工作单元;若写成非递归算法,一般可能比较长,算法本身占用的存储空间较多,但运行时可能需要较少的存储单元。
(1)S(n)
一个算法的空间复杂度只考虑在运行过程中为变量分配的存储空间的大小,记为S(n),它包括:
1)函数参数表中形参变量分配的存储空间。
2)函数体中定义的局部变量分配的存储空间。
若一个算法为递归算法,其空间复杂度为递归所使用的栈空间的大小,它等于一次调用所分配的临时存储空间的大小乘以被调用的次数。
(2)大O函数
与时间复杂度类似,算法的空间复杂度一般也以数量级的形式(O(n))给出。
一般而言:
1)当一个算法的空间复杂度S(n)为一个常量,即不随被处理数据量n的大小而改变时,可表示为O(1)。(如冒泡排序。)
2)当一个算法的空间复杂度S(n)与以2为底的n的对数成正比时,可表示为O(log n)。
3)当一个算法的空间复杂度S(n)与n成线性比例关系时,可表示为O(n)。(如归并排序。)
特殊的:
1)若形参为数组,则只需要为它分配一个用于存储由实参传送来的一个地址指针的空间,即一个机器字长空间。
2)若形参为引用方式,则也只需要为其分配用于存储一个地址的空间,即用它来存储对应实参变量的地址,以便由系统自动引用实参变量。
在竞赛里,内存限制一般为128MB(或256MB),一般都足够用。

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

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

相关文章

go如何从入门进阶到高级

针对Go语言的学习&#xff0c;不同阶段应采取不同的学习方式&#xff0c;以达到最佳效果.本文将Go的学习分为入门、实战、进阶三个阶段&#xff0c;下面分别详细介绍 一、社区 Go语言中文网 作为专注于Go语言学习与推广的平台&#xff0c;Go语言中文网为开发者提供了丰富的中…

苹果系统MacOS下ObjectC建立的App程序访问opencv加载图片程序

前言 苹果系统下使用opencv感觉还是有些不太方便&#xff0c;总是感觉有点受到限制。本博客描述的是在MacOS下建立App程序然后调用opencv显示图片时出现的一些问题并最后解决的一个过程。 一、程序的建立 选择程序的类型&#xff1a; 选择界面模式和编程语言&#xff1a; 其余…

Nginx——入门介绍、安装与核心配置文件结构(一/五)

目录 1.Nginx 简介1.1.背景介绍1.2.名词解释1.3.常见服务器对比1.3.1.IIS1.3.2.Tomcat1.3.3.Apache1.3.4.Lighttpd1.3.5.其他的服务器 1.4.Nginx 的优点1.4.1.速度更快、并发更高1.4.2.配置简单&#xff0c;扩展性强1.4.3.高可靠性1.4.4.热部署1.4.5.成本低、BSD 许可证 1.5.Ng…

【HarmonyOS-ArkTS语言】计算器的实现【合集】

目录 &#x1f60b;环境配置&#xff1a;华为HarmonyOS开发者 &#x1f3af;学习小目标&#xff1a; &#x1f4fa;演示效果&#xff1a; &#x1f4d6;实验步骤及方法&#xff1a; 1. 在index.ets文件中通过 Extend(Button) 装饰器扩展Button 组件设置按钮样式函数myButt…

【C语言程序设计——选择结构程序设计】预测你的身高(头歌实践教学平台习题)【合集】

目录&#x1f60b; 任务描述 相关知识 1、输入数值 2、选择结构语句 3、计算结果并输出 编程要求 测试说明 通关代码 测试结果 任务描述 本关任务&#xff1a;编写一个程序&#xff0c;该程序需输入个人数据&#xff0c;进而预测其成年后的身高。 相关知识 为了完成本…

【连续学习之LwM算法】2019年CVPR顶会论文:Learning without memorizing

1 介绍 年份&#xff1a;2019 期刊&#xff1a; 2019CVPR 引用量&#xff1a;611 Dhar P, Singh R V, Peng K C, et al. Learning without memorizing[C]//Proceedings of the IEEE/CVF conference on computer vision and pattern recognition. 2019: 5138-5146. 本文提…

【微服务】3、配置管理

微服务配置管理 已掌握的微服务组件及配置管理问题引出 已掌握注册中心、Openfan、远程调用、负载均衡、网关等组件&#xff0c;具备微服务开发能力&#xff0c;但仍存在其他问题待解决。微服务和网关存在大量配置文件&#xff0c;其中包含很多重复配置&#xff0c;如数据库、日…

【论文+源码】基于Spring和Spring MVC的汉服文化宣传网站

为了实现一个基于Spring和Spring MVC的汉服文化宣传网站,我们需要创建一个简单的Web应用程序来展示汉服文化和相关信息。这个系统将包括以下几个部分: 数据库表设计:定义文章、用户和评论的相关表。实体类:表示数据库中的数据。DAO层接口及MyBatis映射文件:用于与数据库交…

Apache Celeborn 在B站的生产实践

背景介绍 Shuffle 演进 随着B站业务的飞速发展,数据规模呈指数级增长,计算集群也逐步从单机房扩展到多机房部署模式。多个业务线依托大数据平台驱动核心业务,大数据系统的高效性与稳定性成为公司业务发展的重要基石。如图1,目前在大数据基础架构下,我们主要采用 Spark、Fl…

计算机网络:网络层知识点及习题(一)

网课资源&#xff1a; 湖科大教书匠 1、概述 网络层实现主机到主机的传输&#xff0c;主要有分组转发和路由选择两大功能 路由选择处理机得出路由表&#xff0c;路由表再生成转发表&#xff0c;从而实现分组从不同的端口转发 网络层向上层提供的两种服务&#xff1a;面向连接…

深入刨析数据结构之排序(上)

目录 1.内部排序 1.1概述 1.2插入排序 1.2.1其他插入排序 1.2.1.1 折半插入排序 1.2.1.2 2-路插入排序 1.3希尔排序 1.4快速排序 1.4.1起泡排序 1.4.2快速排序 1.4.2.1hoare版本 1.4.2.2挖坑版本 1.4.2.3前后指针版本 1.4.2.4优化版本 1.4.2.4.1小区间插入排序优…

卸载wps后word图标没有变成白纸恢复

这几天下载了个wps教育版&#xff0c;后头用完了删了 用习惯的2019图标 给兄弟我干没了&#xff1f;&#xff1f;&#xff1f; 其他老哥说什么卸载关联重新下 &#xff0c;而且还要什么撤销保存原来的备份什么&#xff0c;兄弟也是不得不怂了 后头就发现了这个半宝藏博主&…

huggingface 下载方法 测试ok

目录 python下载方法&#xff1a; 设置环境变量 ~/.bashrc 缓存目录&#xff0c;默认模型下载目录 安装方法&#xff1a; python 下载无token&#xff1a; python 下载带token 常见报错 登录后创建Read token 2.3 创建token 使用token登录 python下载方法&#xff1…

【网络安全技术与应用】(选修)实验8 入侵检测

参考内容:【入侵检测】window下安装snort_windows安装snort-CSDN博客 一、实验目的 深入理解入侵检测系统的原理和工作方式,熟悉入侵检测工具Snort在Windows操作系统中的安装、配置及使用方法。二、实验内容 安装WinPcap及Snort;启动Snort;自编写简单的报警规则并进行测试;…

Linux驱动开发 gpio_get_value读取输出io的电平返回值一直为0的问题

当时gpio子系统进行读取时返回必定是0 因此&#xff0c;首先必须使用platform驱动来管理gpio和pinctrl子系统&#xff0c;然后如果按照正点原子所教的设备树引脚设置为0x10B0则会导致读取到的电平值为0。 解决方法&#xff1a; 将设备树中的引脚设置为 pinctrl_gpioled: gpio…

CDP集成Hudi实战-spark shell

[〇]关于本文 本文主要解释spark shell操作Hudi表的案例 软件版本Hudi1.0.0Hadoop Version3.1.1.7.3.1.0-197Hive Version3.1.3000.7.3.1.0-197Spark Version3.4.1.7.3.1.0-197CDP7.3.1 [一]使用Spark-shell 1-配置hudi Jar包 [rootcdp73-1 ~]# for i in $(seq 1 6); do s…

web实操9——session

概念 数据保存在服务器HttpSession对象里。 session也是域对象&#xff0c;有setAttribute和getAttribute方法 快速入门 代码 获取session和塞入数据&#xff1a; 获取session获取数据&#xff1a; 请求存储&#xff1a; 请求获取&#xff1a; 数据正常打印&#xff1a…

常用LabVIEW算法及应用

在LabVIEW项目中&#xff0c;算法的应用是提高系统性能、实现特定功能、完成复杂任务的核心。LabVIEW作为一种图形化编程语言&#xff0c;允许用户通过直观的图形编程来实现各种复杂的算法。这些算法广泛应用于控制系统、数据采集、信号处理、图像处理、机器学习等领域。了解常…

AI Agent 开发共学招募 | 来 Sui 上探索自治智能的边界

Agent 一词源自拉丁语 “Agere”&#xff0c;意为“行动&#xff08;to do&#xff09;”。在大语言模型&#xff08;LLM&#xff09;的语境下&#xff0c;Agent 指的是能够感知环境、进行决策并执行任务的智能实体。 与传统的 RPA 相比&#xff0c;后者只能在预设的条件下执行…

安卓NDK视觉开发——手机拍照文档边缘检测实现方法与库封装

一、项目创建 创建NDK项目有两种方式&#xff0c;一种从新创建整个项目&#xff0c;一个在创建好的项目添加NDK接口。 1.创建NDK项目 创建 一个Native C项目&#xff1a; 选择包名、API版本与算法交互的语言&#xff1a; 选择C版本&#xff1a; 创建完之后&#xff0c;可…