二分查找递归与非递归的时间比较_Algorithm:递归思路及实例分析

递归思路

1、找重复:找出子问题

2、找变化:变化的量应该作为参数;

3、找边界:设计函数的出口;

T 1:求阶乘

输入n,使用递归的方法输出n!

int Rec(int n){    if(n==1)        return 1;    return n*Rec(n-1);}

T 2:求数组元素和

对arr的所有元素求和

int Rec(vector arr,int begin){    if (begin == arr.size() - 1)        return arr[begin];    return arr[begin] + Rec(arr,begin + 1);}

T 3:斐波那契数列

f(0)=1

f(1)=1

f(2)=f(0)+f(1)=2

f(3)=f(1)+f(2)=3

f(n)=f(n-2)+f(n-1)

输入n,求f(n)

int Feb(int n){    if(n==0 || n==1)        return 1;	return Feb(n-2)+Feb(n-1);	}

T 4:最大公约数

输入m,n,求它俩的最大公约数(m>n)

f08aba1d8c429ec658665d3bb6ac84ba.png
img
int Rec(int m,int n){    if(n==0)        return n;    return Rec(n,m%n)}

T 5:插入排序改递归

使用递归的方法对数组arr进行排序;

fcdb327e62e80db43c728b1a05084b0e.png
void insertSort(vector &arr, int pos)//对arr[0]-arr[pos]进行排序{	if (pos == 0)		return;	insertSort(arr, pos - 1);//等pos前面的元素都排序完了,我再对pos元素进行排序;	int p = pos;	int val = arr[p];	while (p > 0 && val < arr[p - 1])//只要比前面的元素小,就继续向前找位置	{		arr[p] = arr[p - 1];		p--;	}    //此时arr[p]>arr[p-1],在此位置插入;	arr[p] = val;}

T 6:汉诺塔问题

A B C三处,将A处的n个盘子移动到C处,每次只能移动1个盘子,下盘子只能放在大盘子上面;

78af7ead864c9aa37076c3bb25bea73d.gif
n=3时
84e8a376c77277e874ccd6a3735793a3.gif
n=6时

1、找重复:把n块盘子从A移动到C,那么我只需叫人通过中介C帮我把n-1个盘子移动到B处,然后我把第n个盘子移动到C处,再叫别人把B处的n-1个盘子通过中介A挪到C处;

2、找变化:移动过程中,「初始地、中介、目的地以及目前移动的哪块盘子」都不一样,这些都是变化量;

3、找边界:如果n==0时,不存在第0块盘子,所以此时什么都不用做,返回即可;

void Hanuo(int n, char begin, char help, char dest){	if (n < 1)		return;	Hanuo(n - 1, begin, dest, help);	cout << "move " << n << " from " << begin << " to " << dest << endl;	Hanuo(n - 1, help, begin, dest);}int main(){	Hanuo(3, 'A', 'B', 'C');	return 0;}

T 7:二分查找的递归算法

对于有序数组arr,输入key,使用递归形式的二分查找方法查找key所对应的索引;

int BinarySearch(vector arr, int left, int right, int key){    if(left > right) //此时表示在数组arr中找不到该key值        return -1;    //二分查找	int mid = left + (right - left) / 2;	if (arr[mid] == key)		return mid;	else if (arr[mid] < key)	{		return BinarySearch(arr, mid + 1, right, key);	}	else	{		return BinarySearch(arr, left, mid - 1, key);	}}

递归性能

递归的时间复杂度取决于子问题的分支数;

比如求阶乘的时间复杂度为O(n),而斐波那契时间复杂度大约为O(2^n^);

9eb1ffcf85d6820f0589a9af08dc2ae7.png

因为分支数越多意味着有更多的「冗余运算」,即多做了很多次重复的计算,这是就需要动态规划或者非递归的迭代形式来降低复杂度;

由于递归重复调用当前函数,函数主要使用栈空间,所以递归的空间复杂度也较高;

但递归有个最大的好处就是:容易理解

总结

「递归就是偷懒」

我解决问题的一个部分,剩下的交给别人处理;或者理解为一个蛋糕,我只切一小块,剩下的怎么分交给别人完成;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值