数据结构 时间复杂度_空间复杂度

Posted 林慢慢i

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数据结构 时间复杂度_空间复杂度相关的知识,希望对你有一定的参考价值。

前言

1.什么是数据结构?

数据结构是计算机存储、组织数据的方式,指相互之间存在一种或多种特定关系的数据元素的集合。

2.什么是算法?

算法就是定义良好的计算过程,他取一个或一组的值作为输入,并产生出一个或一组值作为输出。简单来说算法就是一系列的计算步骤,用来将输入数据转化成输出结果。

正文

1.算法效率

算法效率分析分为两种:时间效率和空间效率。时间效率被称为时间复杂度,而空间效率被称作空间复杂度。时间复杂度主要衡量的是一个算法的运行速度,而空间复杂度主要衡量一个算法所需要的额外空间。

2.时间复杂度

2.1时间复杂度的定义

在计算机科学中,算法的时间复杂度是一个函数,他定量描述了该算法的运行时间。一个算法所花费的时间与其中语句的执行次数成正比例,算法中的基本操作的执行次数,为算法的时间复杂度

2.2大O渐进表示法

在实际中一般情况关注的是算法的最坏运行情况,所以数组中擭索数据时间复杂度为O(N)

(1)可以忽略加法常数

O(2n + 3) = O(2n)

(2)与最高次项相乘的常数可忽略

O(2n^2) = O(n^2)

(3) 最高次项的指数大的,函数随着 n 的增长,结果也会变得增长得更快

O(n^3) > O(n^2)

(4)判断一个算法的(时间)效率时,函数中常数和其他次要项常常可以忽略,而更应该关注主项(最高阶项)的阶数

O(2n^2) = O(n^2+3n+1)
O(n^3) > O(n^2)

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

实际中我们计算时间复杂度时,我们其实并不一定要计算精确的执行次数,而只需要大概执行次数,那么这里我们使用大O的渐进表示法。
大O符号( Big O notation):是用于描述函数渐进行为的数学符号。

推导大O阶方法:

1、用常数1取代运行时间中的所有加法常数

2、在修改后的运行次数函数中,只保留最高的项

3、如果最高阶项存在且不是1,则去除与这个项目相乘的常数。得到的结果就是大O阶

使用大O的渐进表示法以后,Func1的时间复杂度为 O(N²)

在这里插入图片描述

总结:

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

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

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

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

最好情况:1次找到

最坏情况:N次找到

平均情况:N/2次找到

常见时间复杂度如下:

在这里插入图片描述

2.3常见时间复杂度计算举例(自己目测下复杂度)
实例1 复杂度: O(N)

在这里插入图片描述

实例2 复杂度: O(1)

在这里插入图片描述

实例3 冒泡排序 复杂度: O(N²)
/* 1. 从当前元素起,向后依次比较每一对相邻元素,若逆序则交换 */
/* 2. 对所有元素均重复以上步骤,直至最后一个元素 */
/* elemType arr[]: 排序目标数组; int len: 元素个数 */
void bubbleSort (elemType arr[], int len) {
    elemType temp;
    int i, j;
    for (i=0; i<len-1; i++) /* 外循环为排序趟数,len个数进行len-1趟 */
        for (j=0; j<len-1-i; j++) { /* 内循环为每趟比较的次数,第i趟比较len-i次 */
            if (arr[j] > arr[j+1]) { /* 相邻元素比较,若逆序则交换(升序为左大于右,降序反之) */
                temp = arr[j];
                arr[j] = arr[j+1];
                arr[j+1] = temp;
            }
        }
}
实例4 斐波那契递归 复杂度: O(2^N) 该算法时间复杂度太高,在实际中意义不大

递归算法的时间复杂度=递归次数*每次递归函数中运行的次数

int fib(int n) {    
    if (n <= 2) {
        return 1;
    }
    return fib(n - 1) + fib(n - 2);
}

在这里插入图片描述

3.空间复杂度

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

一个算法所需的存储空间用f(n)表示,空间复杂度的计算公式记作:S(n)=O(f(n)) 。(其中n为问题的规模,S(n)表示空间复杂度)

3.1计算方法
(1)忽略常数,用O(1)表示

举例1:使用了常数个额外空间

在这里插入图片描述

(2)递归算法的空间复杂度=递归深度N*每次递归所要的辅助空间

举例2:递归调用了N次,开辟了N个栈帧,每个栈帧使用了常数个空间。空间复杂度为O(n*1)=O(n)。

def fun(n):
    k = 10
    if n == k:
        return n
    else:
        return fun(++n)
 
3.2 总结:

一般情况下,一个程序在机器上执行时:除了需要存储程序本身的指令,常数,变量和输入数据外 还需要存储对数据操作的存储单元的辅助空间。

若输入数据所占空间只取决于问题本身,和算法无关。这样就只需要分析该算法在实现时所需的辅助单元即可。若算法执行时所需的辅助空间相对于输入数据量而言是个常数,则称此算法为原地工作,空间复杂度为O(1)

4.常用的算法的时间复杂度和空间复杂度

在这里插入图片描述

对各类算法时间/空间复杂度详细分析感兴趣的可以查看这位大佬的博客:https://www.cnblogs.com/angelye/p/7508292.html

以上是关于数据结构 时间复杂度_空间复杂度的主要内容,如果未能解决你的问题,请参考以下文章

数据结构 时间复杂度_空间复杂度

排序02-直接插入排序法

复杂度分析1

数据结构&算法_算法基础之前传(递归时间复杂度空间复杂度二分查找)

关于代码片段的时间复杂度

以下代码片段的时间复杂度是多少?