算法基础
算法概念
时间复杂度
- 时间复杂度:用来评估算法运行效率的一个式子
时间复杂度强调的是一个大概的时间(取最高阶)
时间复杂度 - 小结
-
时间复杂度是用来估计算法运行时间的一个式子(单位)。
-
一般来说,时间复杂度高的算法比复杂度低的算法慢。
-
常见的时间复杂度(按效率排序)
-
-
复杂问题的时间复杂度
-
如何简单快速地判断算法复杂度
-
快速判断算法复杂度(适用于绝大多数简单情况):
- 确定问题规模
- 循环减半过程 --->
- k层关于n的循环 --->
-
复杂情况:根据算法执行过程判断
空间复杂度
-
空间复杂度:用来评估算法内存占用大小的式子
-
空间复杂度的表示方式与时间复杂度完全一样
- 算法使用了几个变量:
- 算法使用了长度为n的一维列表:
- 多算法使用了m行n列的二维列表:
-
“空间换时间”【时间的优先级比较高】
复习:递归
在上面的代码中,func1、func2、func3 和 func4 都是递归函数,因为它们都调用了自身。然而,正确的递归函数需要有一个终止条件来防止无限递归。我们来分析一下每个函数:
func1:没有终止条件。这个函数会无限地递减x并打印它,直到程序崩溃或者遇到栈溢出错误。func2:同样没有终止条件。这个函数在x大于0时会无限地递增x并打印它,直到程序崩溃或者遇到栈溢出错误。func3:有终止条件。当x不再大于0时,递归将停止。这个函数会打印从x开始递减到1的所有正整数。func4:也有终止条件。与func3类似,当x不再大于0时,递归将停止。不同的是,这个函数会在返回之前打印x,所以它实际上会以升序打印从1到x的所有正整数。
因此,正确的递归函数是 func3 和 func4,因为它们有适当的终止条件。
#include <iostream>
void func3(int x) {
if (x > 0) {
std::cout << x << std::endl;
func3(x - 1);
}
}
void func4(int x) {
if (x > 0) {
func4(x - 1);
std::cout << x << std::endl;
}
}
int main() {
std::cout << "func3:" << std::endl;
func3(5); // 示例调用func3,将打印5到1的数字
std::cout << "func4:" << std::endl;
func4(5); // 示例调用func4,将打印1到5的数字
return 0;
}
汉诺塔问题
#include<iostream>
using namespace std;
//汉诺塔问题
//起始杆A 中转杆B 目标杆C
void hanoi(int n, char a, char b, char c)
{
if (n > 0)
{
hanoi(n - 1, a, c, b);
printf("moving from %c to %c\n", a, c);
hanoi(n - 1, b, a, c);
}
}
int main()
{
int n = 3;
char a = 'A';
char b = 'B';
char c = 'C';
hanoi(n, a, b, c);
system("pause");
return 0;
}
moving from A to C
moving from A to B
moving from C to B
moving from A to C
moving from B to A
moving from B to C
moving from A to C
请按任意键继续. . .
- 汉诺塔移动次数的递推式:
- 假设婆罗门每秒钟搬一个盘子,则总共需要5800亿年!