递归和分治思想
如果可以使用迭代,尽量别使用递归。由编译原理可以知道,每次自调用的时候,计算机都需要保存在调用,浪费时间空间。当然,迭代是当我们知道循环次数的时候。而当我们不知道循环次数,比如说对于文件夹和文件进行遍历,不知道深度的情况下,我们就需要递归来实现。
显然,递归是先解决小的问题,这种思想是分治思想。根据具体需求,来决定是否使用递归。
递归要注意:
- 结构是选择结构,而迭代是循环结构
- 必须有基线条件和递归条件,防止出现死循环
- 如果知道循环次数的话,尽量使用递归
- 对于某些编程式函数,有对于尾递归的迭代优化
- 递归逻辑更容易理解
一些实例
逆序输出字符串
#include<iostream>
using namespace std;
void print(){
char a;
cin>>a;
if(a!='#') print(); // 不是停止符,先自调用
if(a!='#') cout<<a; //在回来的时候,打印自己的字符
}
int main(){
print();
return 0;
}
查找数组元祖是否存在
很多时候我们需要查找一个数组中是否有一个元素。如果使用迭代,肯定十分简单,时间复杂度为O(n)。
此时,如果使用分而治之的思想,我们可以使用二分法来进行查找。不论多大的数据,时间复杂度显著降低为O(log_2 n)。也就是说一个大小为123456789的数组,使用迭代,我们需要123456789个时间单位。但是二分法只需要27次。
实现思路:
1. 首先转化的思想对数组进行排序。如果不排序,那么low和high就没有意义了。
2. 再用迭代进行二分
#include<iostream>
#include<algorithm>
using namespace std;
const int SIZE = 5;
const int NONE = -1;
//二分查找并且返回element的位置,没查找到则返回NONE
template<class T>