数据结构:时间复杂度和空间复杂度

目录

  • [1. 如何衡量一个算法的好坏](#1. 如何衡量一个算法的好坏)
  • [2. 算法效率](#2. 算法效率)
  • [3. 时间复杂度](#3. 时间复杂度)
    • [3.1 时间复杂度的概念](#3.1 时间复杂度的概念)
    • [3.2 大O的渐进表示法](#3.2 大O的渐进表示法)
    • [3.3 推导大O阶方法](#3.3 推导大O阶方法)
    • [3.4 常见时间复杂度计算举例](#3.4 常见时间复杂度计算举例)
  • 3.空间复杂度

1. 如何衡量一个算法的好坏

下面求斐波那契数列的算法好还是不好,为什么?该如何衡量一个算法的好坏呢?

java 复制代码
public static long Fib(int N){
    if(N < 3){
        return 1;
    }
    return Fib(N-1) + Fib(N-2);
 }

我们通过时间效率和空间效率来进行衡量,接下来就带大家一起来看看如何计算时间效率和空间效率。(优先看时间)

2. 算法效率

算法效率分析分为两种:第一种是时间效率,第二种是空间效率。时间效率被称为时间复杂度,而空间效率被称作空间复杂度。 时间复杂度主要衡量的是一个算法的运行速度,而空间复杂度主要衡量一个算法所需要的额外空间,在计算机发展的早期,计算机的存储容量很小。所以对空间复杂度很是在乎。但是经过计算机行业的迅速发展,计算机的存储容量已经达到了很高的程度。所以我们如今已经不需要再特别关注一个算法的空间复杂度。

3. 时间复杂度

3.1 时间复杂度的概念

时间复杂度的定义:在计算机科学中,算法的时间复杂度是一个数学函数 ,它定量描述了该算法的运行时间。一个算法执行所耗费的时间,从理论上说,是不能算出来的,只有你把你的程序放在机器上跑起来,才能知道。但是我们需要每个算法都上机测试吗?是可以都上机测试,但是这很麻烦,所以才有了时间复杂度这个分析方式。一个算法所花费的时间与其中语句的执行次数成正比例,算法中的基本操作的执行次数,为算法的时间复杂度

思考

我们要衡量一段代码时间复杂度通过执行开始到执行结束的时间吗?

答案显然错误的,因为在性能不同的电脑上相同的代码运行时间同样会有所差异。

下面我们来介绍时间复杂度的计算方法:大O的渐进表示法

3.2 大O的渐进表示法

java 复制代码
//请计算一下func1基本操作执行了多少次?
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--) > 0) {
 count++;
 }
 System.out.println(count);
 }

实际中我们计算时间复杂度时,我们其实并不一定要计算精确的执行次数,而只需要大概执行次数,那么这里我们使用大O的渐进表示法。

大O符号(Big O notation):是用于描述函数渐进行为的数学符号。

3.3 推导大O阶方法

通过上面我们会发现大O的渐进表示法去掉了那些对结果影响不大的项 ,简洁明了的表示出了执行次数。
另外有些算法的时间复杂度存在最好、平均和最坏情况

最坏情况:任意输入规模的最大运行次数(上界)

平均情况:任意输入规模的期望运行次数

最好情况:任意输入规模的最小运行次数(下界)

例如:在一个长度为N数组中搜索一个数据x

最好情况:1次找到

最坏情况:N次找到

平均情况:N/2次找到
因此,如果没有特殊说明我们所说的时间复杂度为最坏情况,所以数组中搜索数据时间复杂度为O(N)

3.4 常见时间复杂度计算举例

实例一

基本操作执行了2N+10次,通过推导大O阶方法知道,时间复杂度为 O(N)

实例二

基本操作执行了M+N次,有两个未知数M和N,时间复杂度为 O(N+M)

实例三

基本操作执行了100次,通过推导大O阶方法,时间复杂度为 O(1)

实例四
基本操作执行最好N次(通过最下面的if语句优化后)最坏执行了(N(N-1))/2次,通过推导大O阶方法+时间复杂度一般看最坏,时间复杂度为O(n2)

实例五

基本操作执行最好1次,最坏log2N次,时间复杂度为 O(log2N)

计算方法:有n个点,第一次查到的点为n/2,第二次查到的点为n/22......

设最坏查了x次查到了最后一个点,因此得到算式:n/2x=1

即2x=n,所以x=log2n,即查了x次为最坏结果

实例六

通过计算分析发现基本操作递归了N次,时间复杂度为O(N)。

实例七

通过计算(等比数列)分析发现基本操作递归了2n次,时间复杂度为O(2N)。

3.空间复杂度

空间复杂度是对一个算法在运行过程中临时占用存储空间大小的量度 。空间复杂度不是程序占用了多少bytes的空间,因为这个也没太大意义,所以空间复杂度算的是变量的个数。空间复杂度计算规则基本跟时间复杂度类似,也使用大O渐进表示法。

实例一

使用了常数个额外空间,所以空间复杂度为 O(1)

实例二

动态开辟了N个空间,空间复杂度为 O(N)

实例三

递归调用了N次,开辟了N个栈帧,每个栈帧使用了常数个空间。空间复杂度为O(N)

相关推荐
熬了夜的程序员3 小时前
【LeetCode】109. 有序链表转换二叉搜索树
数据结构·算法·leetcode·链表·职场和发展·深度优先
立志成为大牛的小牛4 小时前
数据结构——四十一、分块查找(索引顺序查找)(王道408)
数据结构·学习·程序人生·考研·算法
前端小L6 小时前
二分查找专题(九):“降维”的魔术!将二维矩阵“拉平”为一维
数据结构·算法
她说人狗殊途6 小时前
时间复杂度(按增长速度从低到高排序)包括以下几类,用于描述算法执行时间随输入规模 n 增长的变化趋势:
数据结构·算法·排序算法
Miraitowa_cheems6 小时前
LeetCode算法日记 - Day 102: 不相交的线
数据结构·算法·leetcode·深度优先·动态规划
野生技术架构师6 小时前
盘一盘Redis的底层数据结构
数据结构·数据库·redis
Miraitowa_cheems6 小时前
LeetCode算法日记 - Day 101: 最长公共子序列
数据结构·算法·leetcode·深度优先·动态规划
北冥湖畔的燕雀6 小时前
std之list
数据结构·c++·list
南方的狮子先生7 小时前
【C++】C++文件读写
java·开发语言·数据结构·c++·算法·1024程序员节
Alex艾力的IT数字空间8 小时前
完整事务性能瓶颈分析案例:支付系统事务雪崩优化
开发语言·数据结构·数据库·分布式·算法·中间件·php