递归(英语:recursion)在计算机科学中是指一种经过重复将问题分解为同类的子问题而解决问题的方法。[1] 递归式方法能够被用于解决不少的计算机科学问题,所以它是计算机科学中十分重要的一个概念。[2] 绝大多数编程语言支持函数的自调用,在这些语言中函数能够经过调用自身来进行递归。计算理论能够证实递归的做用能够彻底取代循环,所以有不少在函数编程语言(如Scheme)中用递归来取代循环的例子。(摘自维基百科)编程
在计算机学里,尾调用是指一个函数里的最后一个动做是返回一个函数的调用结果的情形,即最后一步新调用的返回值直接被当前函数的返回结果。[1]此时,该尾部调用位置被称为尾位置。尾调用中有一种重要而特殊的情形叫作尾递归。通过适当处理,尾递归形式的函数的运行效率能够被极大地优化。[1]尾调用原则上均可以经过简化函数调用栈的结构而得到性能优化(称为“尾调用消除”),可是优化尾调用是否方即可行取决于运行环境对此类优化的支持程度如何。(摘自维基百科)性能优化
【编程题】幂运算三(递归函数)
题目ID:1137
【问题描述】 求x^n。
【输入形式】一行2个数,第一个整数表示x,第二个大于等于零的整数表示n,二数之间用空格分隔。
【输出形式】一行一个整数,表示x的n次方
【样例输入】2 3
【样例输出】8编程语言
【样例说明】2的3次方结果为8
【评分标准】5组测试用例,每组2分,共计10分 函数
【测试用例】
1)
输入:
2 3
输出:
8
2)
输入:
3 5
输出:
243性能
3)
输入:
-17 4
输出:
83521测试
4)
输入:
22 0
输出:
1优化
5)
输入:
-1287 0
输出:
1spa
//普通递归 #include<stdio.h> long my_pow1(long x,int n){ if(n==0) return 1; //递归出口 return x*(my_pow1(x,--n)); //除了调用自身外还乘多了个x,即通常的递归 } int main(){ long x; int n; scanf("%ld%d",&x,&n); printf("%ld\n",my_pow1(x,n)); return 0; }
解释:
普通的递归过程是在一个函数中,结果依靠自身的调用来得出,例如求幂运算,pow(2,3)
表明求2的3次方,因为pow(2,3)
未知,咱们能够把它分解成2*pow(2,2),pow(2,2)也未知,又可分解成2*pow(2,1),以此类推,直到pow(2,0)可知(if中定义0时返回1),即pow(2,0)返回值是1.
在这个递归过程当中,pow函数的创建就是一个个压栈的过程
我把它称为函数栈3d
压栈压入因此函数后,直到最后一个,能够得到最后一个函数的返回值,由这个返回值能够依次推出栈内全部函数的返回值(回溯),即退栈,pow(2,0)返回1,推的pow(2,1)返回2*pow(2,0),即2*1=2,pow(2,2)返回2*pow(2,1),即2*2=4,直到退到栈内最后一个函数pow(2,3),可得到pow(2,3)的返回值为2*pow(2,2)即8;
code
【编程题】吃糖(尾递归函数)
题目ID:1135
【问题描述】小樱是个爱吃糖的女孩, 哥哥送了她n(1<=n<=30)颗糖,怎么吃?一天吃1颗;一天吃2颗。嗯,那就天天吃一颗或两颗吧。
1颗糖,确定只有(1)一种吃法;2颗糖,有(1,1)和(2)两种吃法;3颗糖,有(1,1,1)、(1,2)和(2,1)三种吃法。注 (2,1)表示第一天吃2颗,次日吃1颗。*
你能帮小樱算出,吃完这n颗糖,有多少种吃法吗?请编写一个尾递归函数来解决此问题
【输入形式】
【测试用例】
1)
输入:
1
输出:
result=1
2)
输入:
4
输出:
result=5
3)
输入:
15
输出:
result=987
4)
输入:
20
输出:
result=10946
5)
输入:
30
输出:
result=1346269
实际上这道题是一个斐波那契数列的变体,可用尾递归函数解决
//尾递归 #include <stdio.h> int ci(int n,int pre,int next) { int sum; if (n==1){ //递归出口(递归和回溯的分界点) return pre; } return ci(n-1,next,pre+next); //除了调用自身外没有其余操做即为尾递归 } int main() { int n; int sum; scanf ("%d",&n); printf ("result=%d",ci(n,1,2)); return 0; }
运行图解
解释:
ci(1,5,8)得到了返回值5,ci(2,3,5)的返回值是ci(1,5,8),也就是5,ci(3,2,3)的返回值是ci(2,3,5),也就是5,ci(4,1,2)的返回值也是5;
而已,ci(4,1,2),4是要求斐波那契变体的第4项,1是第一项,2是第二项,从4减到1起到一个计数做用,1和2也是做为递推的起点
*下图是普通递归和尾递归的执行图示: