1.算法效率
算法效率可以用来衡量一个算法的好坏 ,算法效率分析分为两种:第一种是时间效率,第二种是空间效率.时间效率被称为时间复杂度,空间效率被称为空间复杂度.时间复杂度主要衡量的是一个算法的运行速度,而空间复杂度主要衡量一个算法所需要的额外空间,在计算机发展的早期,计算机的存储容量很小。所以对空间复杂度很是在乎。但是经过计算机 行业的迅速发展,计算机的存储容量已经达到了很高的程度。所以我们如今已经不需要再特别关注一个算法的空间复杂度。
2.时间复杂度
2.1时间复杂度为什么不使用时间来衡量而使用基本语句的运行次数来衡量
在计算机科学中,算法的时间复杂度是一个函数,它定量描述了该算法的运行时间。一个算法执行所耗费的时间,从理论上说,是不能算出来的,只有你把你的程序放在机器上跑起来,才能知道。但是上机测试非常的麻烦,而且不同的硬件不同的机器运行的时间是不同的,所以才有了时间复杂度这个分析方式。一个算法所花费的时间与其中语句的执行次数成正比例,算法中的基本操作的执行次数,为算法的时间复杂度。
2.2时间复杂度的O渐进表示法
1.用常数1取代运行时间中的所有加法常数.
2.在修改后的运行次数函数中,只保留最高阶项.
3.如果最高阶项存在且不是1,则去除与这个项目相乘的常数.
最终得到的结果就是大O阶.
例:
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);
}
这个函数的运行时间的函数式为
F(N) = N2 + 2 * N + 10
用大O的渐进表示法后,时间复杂度为
O(N2)
2.3时间复杂度的:最优、平均、最差情况,为什么时间复杂度看的是最差情况?
最差的情况也是该算法存在的可能性之一,有出现最差现象的可能,如果出现最差现象时,此时时间复杂度不能满足我们的要求,那么这个算法是存在问题的,换而言之,如果最差的情况都符合要求,那么其他情况肯定也符合要求.
3.求解:二分查找、递归求阶乘、递归斐波那契的时间复杂度?
3.1二分查找
int BinarySearch(int arr[],int x,int size) {
int left = 0;
int right = size;
while (right >= left) {
int y = (right + left) / 2;
if (x > arr[y]) {
left = y + 1;
}
else if (x < arr[y]) {
right = y - 1;
}
else {
return y;
}
}
return -1;
}
这个算法基本操作执行最少1次,最多O(logN)次,所以时间复杂度为 O(logN)
(logN在算法分析中表示是底数为2,对数为N。有些地方会写成lgN。)
3.2递归求阶乘
long long Factorial(size_t N) {
return N < 2 ? N : Factorial(N-1)*N;
}
这个算法基本操作递归执行了N次,时间复杂度为O(N)
3.3递归斐波那契
long long Fibonacci(size_t N) {
return N < 2 ? N : Fibonacci(N-1)+Fibonacci(N-2);
}
这个算法基本操作递归了2N次,时间复杂度为O(2N)
4. 空间复杂度
空间复杂度是对一个算法在运行过程中临时占用存储空间大小的量度 。空间复杂度不是程序占用了多少bytes的空间,算的是变量的个数。空间复杂度计算规则基本跟时间复杂度类似,也使用大O渐进表示法。
5.如何求空间复杂度? 普通函数&递归函数
空间复杂度计算的是变量的个数,没有借助辅助空间,空间复杂度就是O(1),动态开辟N个空间,空间复杂度就是O(N)
递归函数调用了N次,就开辟了N个栈帧,空间复杂度就是O(N)
6.分析递归斐波那契数列的:时间、空间复杂度,并对其进行优化,伪递归优化—>循环优化
递归:
long long Fibonacci(size_t N) {
return N < 2 ? N : Fibonacci(N-1)+Fibonacci(N-2);
}
(递归过程是一个二叉树,节点个数就是时间复杂度,树的高度是空间复杂度)
时间复杂度为O(2N)
空间复杂度为O(N)
尾递归:
long long Fib(long long n,long long first,long long second)
{
if (n < 3)
{
return second;
}
if(n==3)
{
return first + second;
}
return Fib(second, first + second, n - 1);
}
时间复杂度为O(N)
空间复杂度为O(1)
循环:
long long fib(long long x)
{
if x<3)
{
return 1;
}
int last2 = 1;
int last1 = 1;
int a=0;//最后一项
for (int n = 3; n <= x; ++n)
{
a = last2 + last1;
last1 = last2;
last2 = a;
}
return a;
}
时间复杂度为O(N)
空间复杂度为O(1)
7常见时间复杂度
O(1),O(N),O(N2), O(N3), O(lgN),O(2N)