您的位置:首页 > 游戏 > 手游 > 办公空间设计经典案例_排名优化怎么做_西安百度首页优化_郑州seo优化外包顾问阿亮

办公空间设计经典案例_排名优化怎么做_西安百度首页优化_郑州seo优化外包顾问阿亮

2024/10/5 15:10:07 来源:https://blog.csdn.net/weixin_64116522/article/details/142636995  浏览:    关键词:办公空间设计经典案例_排名优化怎么做_西安百度首页优化_郑州seo优化外包顾问阿亮
办公空间设计经典案例_排名优化怎么做_西安百度首页优化_郑州seo优化外包顾问阿亮

目录

  • 时间复杂度
  • 空间复杂度

时间复杂度

计算时间复杂度时,我们只需计算大致执行次数,再用大O的渐进表示法就可以了

常见的复杂度为O(N),O(1),O(N^2)的几个情况这里就不提了,下面是几个相对来说需要分析的算法

算法1:

// 计算strchr的时间复杂度?
const char * strchr ( const char * str, int character );

这是一个在字符串中找到指定字符的函数,它的时间复杂度分为最好情况、最坏情况和平均情况
最好的情况:首字符就是指定的字符,此时时间复杂度为:O(1)
最坏的情况:最后一个字符才是指定的字符,所以需要从头遍历一遍字符串,时间复杂度为O(N)

一般情况下,关注最坏的情况
所以此函数的时间复杂度为O(N)


算法2:
// 计算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;}
}

最好情况:当数组为有序的时候,只需比较n-1次,所以此时的时间复杂度为O(N)
最坏情况:当数组为乱序的时候,比较的次数如下图,所以时间复杂度为O(N^2)
在这里插入图片描述

如果在上面的函数中,去掉exchange ,那么最好情况和最坏情况下的时间复杂度都为O(N^2)
因为在最好情况下,比较完第一轮之后,虽然已经有序,但是还是会进行第二轮比较


算法3:
// 计算BinarySearch的时间复杂度?
int BinarySearch(int* a, int n, int x)
{assert(a);int begin = 0;int end = n-1;// [begin, end]:begin和end是左闭右闭区间,因此有=号while (begin <= end){int mid = begin + ((end-begin)>>1);if (a[mid] < x)begin = mid+1;else if (a[mid] > x)end = mid-1;elsereturn mid;}return -1;
}

最好情况:当数组下标为(begin +end)/2的值为指定要查找的值时,一次循环都不需要进行,所以时间复杂度为O(1)
最坏情况:不断地二分查找,直到一侧只剩一个值,不能再二分的情况下
N*(1/2)^n = 1
所以n = log2N
最坏情况下,时间复杂度为O(logN)


算法4:
// 计算阶乘递归Fac的时间复杂度?
long long Fac(size_t N)
{if(0 == N)return 1;return Fac(N-1)*N;
}

时间复杂度为O(N),如下图:
在这里插入图片描述


算法5:

// 计算斐波那契递归Fib的时间复杂度?
long long Fib(size_t N)
{if(N < 3)return 1;return Fib(N-1) + Fib(N-2);
}

和上一个算法类似,也是一层一层地调用,如下图,时间复杂度为O(2^N)
在这里插入图片描述



空间复杂度

空间复杂度,是一个算法在运行过程中临时占用的额外存储空间大小的度量
空间复杂度算的是变量的个数

注意:函数运行时所需要的栈空间(存储参数、局部变量、一些寄存器信息等)在编译期间已经确定好了,因此空间复杂度主要通过函数在运行时候显式申请的额外空间来确定。

算法1:

// 计算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)


算法2:

// 计算Fibonacci的空间复杂度?
// 返回斐波那契数列的前n项
long long* Fibonacci(size_t n)
{if(n==0)return NULL;long long * fibArray = (long long *)malloc((n+1) * sizeof(long long));fibArray[0] = 0;fibArray[1] = 1;for (int i = 2; i <= n ; ++i){fibArray[i] = fibArray[i - 1] + fibArray [i - 2];}return fibArray;
}

动态开辟出了n-1个long long大小的空间,所以空间复杂度为O(N)


算法3:

// 计算阶乘递归Fac的空间复杂度?
long long Fac(size_t N)
{if(N == 0)return 1;return Fac(N-1)*N;
}

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

算法4:

// 计算斐波那契递归Fib的时间复杂度?
long long Fib(size_t N)
{if(N < 3)return 1;return Fib(N-1) + Fib(N-2);
}

这个算法的空间复杂度为O(N)而不是O(2^N)

在讲解这个之前,先讲解一个类似原理的情况:

void testa()
{int a;printf("%p\n",&a);
}
void testb()
{int b;printf("%p\n",&b);
}
int main()
{testa();testb();return 0;
}

这段代码的运行结果为:输出的2个地址是相同的
因为先调用testa函数,建立了一个testa的栈帧,运行完testa后,它对应的栈帧销毁
然后调用testb函数,所以testb的栈帧就建立了在原先testa的位置,所以输出的2个地址是相同的

分析以下Fib这个递归函数,它的执行过程类似于一个二叉树,只有把当前左子树执行完,才会执行右子树,而右子树建立的栈帧就会建立在左子树的位置上,所以空间复杂度为O(N)

例如,执行Fib(3)后,先执行Fib(2),建立了对应的栈帧,执行完Fib(2)后,栈帧销毁,接着执行Fib(1),Fib(1)的栈帧建立在之前Fib(2)的位置,所以本质上并未额外开辟空间

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com