算法的时间复杂度和空间复杂度
Posted 軒邈
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了算法的时间复杂度和空间复杂度相关的知识,希望对你有一定的参考价值。
/*
2022.06.04
目的:
浅学算法时间复杂度和空间复杂度
理论:
1.算法设计要求:
a.正确性;
b.可读性;
c.健壮性(当输入的数据不合法时,算法也能够做出相应的处理,而不是产生异常或者莫名奇妙的结果);
d.时间效率高和存储量低;
2.算法效率的度量方法:
a.事后统计法:一个算法运行的时间比较依赖于计算机软件和硬件等环境因素,并且算法的测试数据设计困难;
b.事前分析估算法:在不考虑计算机软件和硬件的因素下,一个程序运行的时间就依赖于算法的好坏和问题输入的规模;
一般利用b来度量一个算法的效率。
3.函数的渐进增长:
举例理解:某个算法,随着n的不断增大,它会优于另外一种算法,或者越来越差于另一算法。
4.时间复杂度:
a.推导大O阶方法:
(1)用常数1取代运行时间中的所有加法常数;
(2)在修改后的运行次数函数中,只保留最高阶项;
(3)如果最高阶项存在且不是1,则去除与这个项目相乘的常数。
最终得到的结果就是大O阶。
b.常数阶:O(1)
c.线性阶:O(n)
d.平方阶:O(nxn)
e.总结:
(1)全部常数项,时间复杂度那么就是常数阶;
(2)全部是多次项,时间复杂度取最高次的项;
(3)时间复杂度不需要考虑系数,系数的影响可以忽略;
(4)时间复杂度耗费时间排序(升序):O(1) < O(logn) < O(n) < O(nlogn) < O(n2) < O(n3) < O(2n) < O(n!) < O(nn)。
5.最坏情况和平均情况:
a.最坏情况-是把所有的包含的情况运行完,通常所说的运行时间都是最坏情况的运行时间;
b.平均情况-是在n/2次后得到需要值的情况,该情况是所有情况中最有意义的,因为它是期望的运行时间。
6.算法的空间复杂度:
a.这里所指的空间是一个算法在运行的过程中,临时占用的存储空间的大小,不是一共用到的存储空间的大小;
b.算法在计算机存储器上所占有的存储空间,包含
存储算法本身所占有的存储空间;
算法的输入输出数据所占用的存储空间;
算法在运行过程中临时占用的存储空间。
c.常见情况:
(1)常量空间——类似于时间复杂度 O(1),当算法的存储空间大小固定,和输入规模没有直接的关系时,空间复杂度记作O(1)。
(2)线性空间——当算法分配的空间是一个线性的集合(如数组),并且集合大小和输入规模 n 成正比时,空间复杂度记作 O(n)。
(3)二维空间——当算法分配的空间是一个二维数组集合,并且集合的长度和宽度都与输入规模 n 成正比时,空间复杂度记作 O(n^2)。
(4)递归空间——纯粹的递归操作的空间复杂度也是线性的,如果递归的深度是n,那么空间复杂度就是 O(n)。
功能:
*/
#include<stdio.h>
#include<string.h>
int main(void)
/* 常数阶O(1) */
/*
解释:
根据推导大O阶方法,用常数1取代运行时间中的所有加法常数;
虽然一共执行了3次,但是平均都是1次,所以还是O(1);
注意:不管执行1次的语句有多少,最终都会记作O(1)。
*/
#if 0
int sum = 0, n = 100; /* 执行一次 */
sum = (1 + n) * n / 2;/* 执行一次 */
printf("%d", sum); /* 执行一次 */
#endif
/* 线性阶O(n) */
/*
解释:
根据推导大O阶方法,因为循环体中的语句需要执行n次,所以时间复杂度是O(n);
*/
#if 0
int i;
for (i = 0; i < n; i++)
printf("%d", i); /* 执行一次 */
#endif
/* 对数阶O(logn) */
/*
解释:
下面的程序是当有多少个2相乘后,可以不满足while循环,所以通过对数换算得对数阶;
*/
#if 0
int count = 1;
while (count < n)
count = count * 2; /* 执行一次 */
#endif
/* 平方阶O(nxn) */
/*
解释:
同样的方法,内循环需要循环n次,外循环需要循环n次,所以两者相乘一共循环n的平方次;
注意:
在式子中系数是可以忽略,这是因为系数的影响是很小的;
*/
#if 0
int i, j;
for (i = 0; i < n; i++)
for (j = 0; j < n; j++)
printf("%d", i + j); /* 执行一次 */
#endif
/* 时间复杂度为O(mxn) */
#if 0
int i, j;
for (i = 0; i < m; i++)
for (j = 0; j < n; j++)
printf("%d", i + j); /* 执行一次 */
#endif
return 0;
以上是关于算法的时间复杂度和空间复杂度的主要内容,如果未能解决你的问题,请参考以下文章