递归的应用

递归的应用


1.用递归实现从0n


(1)

void f1(int n){
    if (n > 0) {
        f1(n-1);//打印0-(n-1)
    }
    printf("%d\n", n);
}



(2)

void f2(int begin,int end){
    if (begin > end) {
        return;
    }
    printf("%d\n",begin);
    f2(begin+1, end);
}



2.计算数组a从下标begin开始到下标end的元素和


(1)

int f3(int a[],int begin, int end){
    if (begin == end) {
        return 0;
    }
    int x = f3(a, begin+1, end);
    return x + a[begin];
}



(2)

int f4(int a[],int end){
    if (end ==0) {
        return 0;
    }
    int x = f4(a, end-1);
    return  x + a[end];
}



3.用递归实现两个字符串是否相同,从前往后进行比较


int f5(char *str1,char *str2){
    if (strlen(str1) != strlen(str2)) {
        return 0;
    }
    if (strlen(str1) ==0) {
        return 1;
    }
    if (str1[0] != str2[0]) {
        return 0;
    }
    return f5(str1+1, str2+1);
}



4.在n个球中任意取出m(不放回),求多少种取法


int f6(int n, int m){
    if ( n < m) {
        return 0;
    }
    if (n == m) {
        return 1;
    }
    if (m == 0) {
        return 1;
    }
    return f6(n-1, m-1)+f6(n-1, m);//n个球中有一个特殊球x,取划分,包含这个x球为f6(n-1, m-1),不包含这个球为f6(n-1, m)
}




5.求n的球的全排列


void f7(char a[],int k , int n){//k表示当前位置与后面的元素交换
    char ch;
    if(k == n ){
        for (int  i =0; i < n; i++) {
            printf("%c",a[i]);
        }
        printf("\n");
    }else{
        for (int i = k; i < n; i++) {//将第k个元素与后面的元素交换,然后调用f7
            if(k != i){
                ch = a[k];
                a[k] = a[i];
                a[i] = ch;//试探
            }
            f7(a, k+1, n);
            if (k != i) {
                ch = a[k];
                a[k] = a[i];
                a[i] = ch;//回溯
            }
        }
    }
}



6.求两个串的最大公共子序列(可以不连续)


int f8(char *str1,char *str2){
    if (strlen(str1) ==0 || strlen(str2) ==0) {
        return 0;
    }
    if (str1[0] == str2[0]) {
        return f8(str1+1, str2+1)+1;
    }else{
        return f8(str1+1, str2)>f8(str1, str2+1) ?f8(str1+1, str2) :f8(str1, str2+1);
    }
}



7.求一个字符串的反串


void change(char str[])
{
    if(*str=='\0')return;
    change(str+1);
    printf("%c",*str);
}


8.计算杨辉三角的第m层的第n元素,m,n从零开始

int f9(int m,int n){
    if (m == 0) {
        return 1;
    }
    if (n == m || n == 0) {
        return 1;
    }
    return f9(m-1, n)+f9(m-1, n-1);
}


9.mA和nB可以有多少种排列

int f9(int m,int n){
    if (m == 0) {
        return 1;
    }
    if (n == m || n == 0) {
        return 1;
    }
    return f9(m-1, n)+f9(m-1, n-1);
}


 递归需要注意的几点:

 1.递归每次调用的层次不同

 2.递归每次调用的形式参数不同

 3.注意返回的次序

=======================================================================================================近期看了《C和指针》里面有一部分简单介绍了递归,感觉对递归又有了新的理解。

记得再我学习C语言的时候,学校的教科书上就是以求阶乘和菲波那切数列为例,编写了相关的代码,但是在求阶乘的函数中递归并没有战术任何优越之处,而在斐波那契数列中,其效率更是极其的低。

使用递归需要的两个特性:

1.存在限制条件,当符合这个限制条件的时候就不在进行递归。

2.每次递归调用之后越来越来接近这个条件限制。

许多问题是以递归形式进行解释和定义的,这样问题就会更清晰。但是,这些问题用迭代的方式实现的时候效率会更高,即使代码的可读性会差一些。当你阅读递归函数的时候,不必纠缠于递归函数的内部调用的细节,只需认为他实现了特定的任务即可。

如果一个递归函数内部所执行的最后一个条语句就是调用自身的话,这个函数就被称为尾部递归,可以很容易的改写成迭代循环的形式,效率会更高一些。

用迭代求阶乘

long factorial ( int n )
{
  long result = 1;
  while ( n > 1 ) {
    result *= n--;
  }
  return result;
}

用迭代求斐波那契数列

long fibonacci ( int n )
{
  long result = 1;
  long pre_result = 1;
  long temp_result = 0;

  while ( n-- > 2)
  {
    temp_result = result;
    result += pre_result;
    pre_result = temp_result;
  }

  return result;
}



 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值