目录
💊1.算法效率
算法效率分为时间复杂度和空间复杂度。
💊2.时间复杂度
💊2.1定义:指的是算法中基本操作的执行次数;
本质上来说是一个函数;
💊2.2.1大O的渐进表示法推导方法(三步)
1,用常数1取代运行时间中的所有加法常数。
2,在修改后的运行次数函数中,只保留最高阶项。
3,如果大O阶项存在且不是1,则去除与这个项目相乘的常数。得到的结果就是大O阶。
下面举一些计算时间复杂度的例子
(1)简单多重循环;
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);
}
分析 :由于上面程序包含一个循环嵌套N * N,一个单循环 2 * N,和while循环M;
所以上面程序的时间复杂度函数可表示为F(N) = N * N + 2 * N + M;
根据大O的渐进表示法则表示为O()
void Func2(int N)
{
int count = 0;
for(int k = 0; k < 2 * N; k++)
{
count++;
}
int M = 10;
while(M--)
{
++count;
}
printf("%d", count);
}
分析 :上面的程序包含一个for循环(2 * N)和while循环(M);
所以上面程序的时间复杂度函数可表示为 :F(N) = 2 * N + M;
用大O的渐进法表示为O(N);(后面的M因为是常数根据大O渐进法所以直接省略)
void Func3 (int N, int M)
{
int count = 0;
for(int k = 0; k < M; k++)
{
count++;
}
for(int k = 0; k < N; k++)
{
count++;
}
printf("%d\n", count);
}
分析 :上面的程序包含两个for循环;
所以上面程序的时间复杂度函数可表示为:F(N) = M + N;
用大O的渐进法表示为O(N + M);
(2)常数次的简单循环:
void Func4(int N)
{
int count = 0;
for(int k = 0; k < 100; k++)
{
count++;
}
printf("%d", count);
}
分析 :只有一个常数次的循环;
用大O的渐进法表示为O(1);
(3)二重循环(进阶):
冒泡排序:
void BubbleSort(int *a, int n)
{
assert(a);
for(int i = n; i > 0; i--)
{
int t = 0;
for(int j - 1; j < n; j++)
{
if(a[j - 1] > a[j])
{
Swap(&a[j - 1], &a[j]);
t = 1;
}
}
if(t == 0)
break;
}
}
分析 : 根据冒泡排序的原理可知每次循环的次数都减一, 第一次循环的次数为(N - 1);
所以循环次数为 (N - 1) + (N - 2) + ......+ 2 + 1;
根据大O的渐进法可得该程序的时间复杂度为O();
(4)二分查找:
int BinarySearch(int * a, int n, int x)
{
assert(a);
int begin = 0;
int end = n;
while(begin < end)
{
int mid = begin + ((end - begin) >> 1);
if(a[mid] < x)
begin = mid + 1;
else if (a[mid] > x)
end = mid;
else
return mid;
}
return -1;
}
分析 :假设数组中有N个根据二分查找的原理可知每次查找范围减半;所以循环的次数X = 该程序的时间复杂度用大O的渐进法表示为O()
(5)递归函数的时间复杂度的计算:
对于递归函数给出计算时间复杂度的公式:递归次数 * 每次递归函数的次数
1 , 递归计算阶乘:
long long Factorial(int N)
{
return N < 2 ? N: Factorial(N - 1) * N;
}
分析:由于每次递归调用一次函数总共调用N次;
所以该程序的时间复杂度为: O( N);
2,递归计算斐波那契数列:
long long Fibonacci(int N)
{
return N < 2 ? N : Fibonacci(N - 1) + Fibonacci(N - 2);
}
分析
故该程序的时间复杂度表示为O(2^(N - 1));
💊3.空间复杂度:
计算的规则是:计算大概定义的变量的个数;
💊3.1有常数变量:
void BubbleSort(int *a, int n)
{
assert(a);
for(int i = n; i > 0; i--)
{
int t = 0;
for(int j - 1; j < n; j++)
{
if(a[j - 1] > a[j])
{
Swap(&a[j - 1], &a[j]);
t = 1;
}
}
if(t == 0)
break;
}
}
分析 :以上程序有常数个变量;
则该程序的空间复杂度为O(1);
💊3.2 递归函数:
递归函数空间复杂度的计算方法:递归的栈帧深度(因为递归函数要建立函数栈帧需要消耗空间)
long long Factorial(int N)
{
return N < 2 ? N: Factorial(N - 1) * N;
}
分析 :由于该程序在递归的过程中递归的栈帧深度为N;
所以该算法的空间复杂度为O(N);
如果以上内容帮到你,请点赞收藏吧;