🍔 个人主页 : 起名字真南
@TOC
1 算法效率
1.1 如何衡量一个算法的好坏
接下来给大家看一个用递归的方式去实现斐波那契数列
long long fib(int N)
{
if (N < 3)
return 1;
return fib(N - 1) + fib(N - 2);
}
输出结果 :
这里计算的是斐波那契数列的 第 6 位是 8
1.2 算法的复杂度
运行一串代码需要占用时间和内存,因此衡量一个代码的好坏需要从 时间和空间和的两个维度进行衡量。
=时间复杂度主要是衡量一串代码运行所需要的时间,空间复杂度书要是主要衡量一个代码所需要额外开辟的空间。
1.3 复杂度在校招中的考察
2 时间复杂度
2.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 < 4 * n; k++)
{
++count;
}
int a = 100;
while (a--)
{
++count;
}
printf("%d", count);
}
int main()
{
int N = 0;
scanf("%d", &N);
Func1(N);
return 0;
}
请你思考一下如果输入的N 的值为4的情况下最后打印出count是多少?
从这里我们可以看到结果是132,那么它是怎么计算的呢?
我们可以看到在最上面有两层for循环进行嵌套所以执行次数为n2,在往下面看是一个单独的for循环执行次数为4*n,在往下面最后是一个while循环定义了一个整形变量a为100,循环条件是a不为0,所以执行的次数为100。
最后我们得出结果为:F(N)=N2+ 4N+100
N | F(N) |
4 | 132 |
100 | 10500 |
10000 | 100040100 |
根据结果显示当N越来越大的时候F(N)≈N2
并且当我们执行一个算法的时候不需要其确定的执行次数而是只需要大概的次数,那么这里就将使用我们的大O
渐进表示法
2.2 大O的渐进表示法
大O符号:是用于描述函数渐进行为的数学符号。 推导方法类似于数学中的求链接: 通项公式
推导大O阶的方法:
- 1、用常数1取代运行时间中的所有加法常数
- 2、在修改后的运行次数函数中,只保留最高阶项
- 3、如果最高阶项存在且不是1,则去除与这个项目相乘的常数。得到的结果就是大O阶。
3 空间复杂度
3.1空间复杂度的概念
空间复杂度也是一个数学表达式,是对一个算法在运行时需要额外开辟空间多少的量度。 注意:函数运行时所需要的栈空间(存储参数,局部变量,一些寄存器信息等)在编译期间已经确定好了,因此空间复杂度只计算函数在运行时所额外需要开辟的空间。
接下来给大家举个例子方便更好的理解空间复杂度
Bubble_sort(int* a, int num)
{
//首先需要确定需要排序的趟数
for (int i = 0; i < num - 1; i++)
{
//每一趟都会找到一个最大值或最小值放在最右侧
//所以每一趟过后需要比较的次数都会少一次
for (int j = 0; j < num - 1 - i; j++)
{
//判断交换的条件
if (a[j] > a[j + 1]) //升序
{
int tmp = 0;
tmp = a[j];
a[j ] = a[j + 1];
a[j + 1] = tmp;
}
}
}
}
void print_arr(int* a,int sz)
{
for (int i = 0; i < sz; i++)
{
printf("%d", a[i]);
}
}
int main()
{
int arr[] = { 2,7,5,4,6,9,3,1,8};
int sz = sizeof(arr) / sizeof(arr[0]);
Bubble_sort(arr, sz);
print_arr(arr,sz);
return 0;
}
从代码中我们可以看到在每一次交换数据的时候都需要额外开辟一个临时的变量来储存数据,并且开辟的数量取决于是否需要交换,开辟的空间是常数个所以用 O(1) 来表示