我希望有个如你你一般的人;
如山间清晨一般明亮清爽的人,如奔赴古城道路上阳光一般的人,
温暖而不炙热,覆盖我所有肌肤。
由起点到夜晚,由山野到书房,一切问题的答案都很简单。
我希望有个如你一般的人,贯彻未来,数遍生命的公路牌!–张嘉佳《从你的全世界路过》
1. 算法和算法分析思维导图
2. 算法
2.1 算法的定义
对特定问题求解步骤的一种描述。
2.2 算法的五个特性
2.2.1 有穷性
一个算法必须总是(对任何合法的输入值)在执行有穷步之后结束,且每一步都在有穷时间内完成。
2.2.2 确定性
算法中的每一条指令必须有确切的含义,使读者理解时不会产生二义性.并且,在任何条件下,算法只有唯一的一条执行路径,即对于相同的输入只能得出相同的结果.
2.2.3 可行性
一个算法是能行的,即算法中描述的操作都是通过已经实现的基本运算执行有限次来实现的.
2.2.4 输入
一个算法有零个或多个的输入,这些输入取自于某个特定的对象的结合.
2.2…5 输出
一个算法有一个或多的输出,这些输出是同输入有着特定关系的量.
2.3 算法设计的要求
2.3.1 正确性
算法应当满足具体问题的需求.
2.3.2 可读性
算法主要是为了人的阅读与交流,其次才是机器执行.
2.3.3 健壮性
当输入数据非法时,算法也能适当地做出反应或进行处理,而不会产生莫名其妙的输出结果.
2.3.4 效率与低存储量需求
效率:算法执行的时间;存储量需求:指算法执行过程中所需要的最大存储空间.
2.3.5 定义
对特定问题求解步骤的一种描述.
2.4 算法好坏的衡量
2.4.1 算法效率的度量( 时间复杂度)
- 定义
算法基本操作所执行的次数,时间复杂度主要衡量的是一个算法的运行速度。
- 大O渐进表示法(Big o notation)
(1)用常数1取代运行时间中的所有加法常数.
(2)在修改后的运行次数函数中,自保留最高阶项.
(3)如果最高阶项存在且不是1,则去除与这个项目相乘的常数,得到的结果就是大O阶.
- 表示
T(n)=O(f(n))
2.4.2 算法的存储空间需求(空间复杂度)
-
定义
是对一个算法在运行过程中临时空间占用存储空间大小的量度,空间复杂度主要衡量一个算法所需要的额外空间。
-
包括
(1)创建变量;
(2)开辟内存空间;
(3)是否借助辅助空间。 -
表示
S(n)=O(f(n))
注意:虽然算法的时间复杂度存在最好、平均及最坏三中情况,但我们通常关注的是算法的最坏运行情况,因为一旦达到了最坏情况,程序就会崩溃,我们应该尽量去避免这样的情况出现。
3.求解:二分查找、递归求阶乘、递归斐波那契的时间复杂度和空间复杂度
3.1 二分查找(BinarySearch)
int BinarySearch(int* arr, int size, int to_find) {
assert(arr);
int left = 0;
int right = size - 1;
while (left <= right) {
int mid = (left + right) / 2;
if (arr[mid] < to_find) {
left = mid + 1;
}
else if (arr[mid] > to_find) {
right = mid - 1;
}
else {
return mid;
}
}
return -1;
}
时间复杂度 O(logN)或者O(lgN)
空间复杂度 O()
3.2 递归求阶乘
#include <stdio.h>
#include <stdlib.h>
int Factor(int n){
if (0 == n || 1 == n){
return 1;
}
else{
return n * Factor(n - 1);
}
}
int main(){
printf("%d\n", Factor(5));
system("pause");
return 0;
}
时间复杂度 O(常量*(N+1)) = O(N)
空间复杂度 O()
3.3 递归菲波那切数列
3.3.1(递归)
long long Fibonacci(int N) {
if (N < 3) {
return 1;
}
else{
return Fibonacci(N - 1) + Fibonacci(N - 2);
时间复杂度O() = O(2^N);
空间复杂度O() = O();
3.3.2(伪递归)
#include <stdio.h>
#include <stdlib.h>
long long Fibonacci(long long first, long long second, int N){
if (N < 3){
return 1;
}
if (N == 3){
return first + second;
}
else{
return Fibonacci(second, first + second, N-1 );
}
}
int main(){
printf("%d\n",Fibonacci(1, 1, 10));
system("pause");
return 0;
}
时间复杂度 O(2^N)
空间复杂度 O(N)
与递归类似,空间复杂度=单次递归中开辟的空间数*递归深度
优化:
空间复杂度会发生改变。假设该程序共开辟了N个栈帧,因为执行过程中递归返回的数并没有做其它的运算,因此会被优化为在一个栈帧中修改数据,最终也就只需要一个栈帧即可,此时
时间复杂度
空间复杂度为:O(1)