算法的复杂度
衡量一个算法的好坏,一般是从时间和空间两个维度来衡量的
时间复杂度主要衡量一个算法的运行快慢,而空间复杂度主要衡量一个算法运行所需要的额外空间。
时间复杂度(是个函数 )
定义:一个算法所花费的时间与其中语句的执行次数成正比例,算法中的基本操作的执行次数,为算法的时间复杂度。
即:找到某条基本语句与问题规模N之间的数学表达式,就是算出了该算法的时间复杂度
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)= n*n + 2*n +10
O(N^2)
大O的渐进表示法
大O符号:是用于描述函数渐进行为的数学符号
推到大O阶方法:
1.用常数1取代运行时间中的所有加法常数
2.在修改后的运行次数函数中,只保留最高阶项
3.如果最高阶项存在且不是1,则去除与这个项目相乘的常数,得到的结果就是大O阶
常数的时间复杂度
void Func2(int N) {
int count = 0;
for (int i = 0; i < 1000; i++)
{
++count;
}
printf("%d\n", count);
}
常数次都是O(1)
计算strchr的时间复杂度
//在字符串查找字母
const char * strchr (const char * str,int character);
当一个算法随着输入不同,时间复杂度不同,时间复杂度做悲观预期,看最坏的情况
O(N)
冒泡排序的时间复杂度
void BubbleSort(int* a, int n) {
assert(a);
for (int end = 0; end = n; --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(n^2 )
递归函数的时间复杂度
long long Fac(size_t N) {
if (0 == N)
return 1;
return Fac(N - 1) * N;
}
O(N)
递归算法:递归次数*每次递归调用的次数
斐波那契函数的时间复杂度
右边的一些递归分支会提前结束
O(2^n)
空间复杂度
对一个算法在运行过程中临时占用存储空间大小的量度
注意:函数运行时所需要的栈空间(存储参数、局部变量、一些寄存器信息等)在编译期间已经确定好了,因此空间复杂度主要通过函数在运行时候显示申请的额外空间来确定
空间是可以重复利用的不累计的