时间复杂度与空间复杂度看这就够了!

时间复杂度和空间复杂度总结

1.算法效率

算法效率分两种,时间效率和空间效率,即时间复杂度和空间复杂度,前者衡量算法运行速度,后者衡量算法所需要的额外空间

2.时间复杂度

2.1基本概念
算法中的时间复杂度是一个函数,定量描述了算法运行时间
总结下来就是:算法种基本操作的执行次数
关注点:操作的数量级/基本操作的执行次数
①执行时间和硬件资源强相关,不同硬件处理速度有差异
②CPU每秒钟执行操作在亿级以上
2.2大O的渐进表示法

// 请计算一下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--) 
{
    
    
 ++count; 
}
printf("%d\n", count);
}

//Func1 执行的基本操作次数 :
N = 10 F(N) = 130
N = 100 F(N) = 10210
N = 1000 F(N) = 1002010
实际中我们计算时间复杂度时,我们其实并不一定要计算精确的执行次数,而只需要大概执行次数,那么这里我们使用大O的渐进表示法。

大O符号(Big O notation):是用于描述函数渐进行为的数学符号。
推导大O阶方法:
1、最高次项有系数,忽略系数
2、如果执行次数为常数次,就为O(1)
3、如果最高阶项存在且不是1,则去除与这个项目相乘的常数。得到的结果就是大O阶。
4.不能依靠循环的嵌套简单腿断时间复杂度,应该具体分析基本操作的执行次数
使用大O的渐进表示法以后,Func1的时间复杂度为:O(n²)

N = 10 F(N) = 100
N = 100 F(N) = 10000
N = 1000 F(N) = 1000000
通过上面我们会发现大O的渐进表示法去掉了那些对结果影响不大的项,简洁明了的表示出了执行次数。
另外有些算法的时间复杂度存在最好、平均和最坏情况:
最坏情况:任意输入规模的最大运行次数(上界)
平均情况:任意输入规模的期望运行次数
最好情况:任意输入规模的最小运行次数(下界)
例如:在一个长度为N数组中搜索一个数据x
最好情况:1次找到
最坏情况:N次找到
平均情况: N/2次找到

3.空间复杂度

官方概念:是对一个算法在运行过程中临时占用存储空间大小的亮度
直白来说:空间复杂度不看程序占用多少B的内存,直接看变量的个数,并且是算法中创建的变量个数

具体实例

// 计算BubbleSort的空间复杂度?
void BubbleSort(int* a, int n) {
    
    
 assert(a);
 for (size_t end = n; end > 0; --end)
 {
    
    
 int exchange = 0;
 for (size_t i = 1; i < end; ++i)
 {
    
    
 if (a[i-1] > a[i])
 {
    
    
 Swap(&a[i-1], &a[i]);
 exchange = 1;
 }
 }
 if (exchange == 0)
 break}
 }

使用常数个额外空间,所以空间复杂度为O(1)
如果算法执行所需要的临时空间不随着某个变量n的大小而变化,所以空间复杂度为一个常量!,可表示为O(1)

// 计算阶乘递归Factorial的空间复杂度?
long long Factorial(size_t N) {
    
    
 return N < 2 ? N : Factorial(N-1)*N; }

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

猜你喜欢

转载自blog.csdn.net/qq_45657288/article/details/109061721