C语言学习笔记:函数递归与迭代+例子

函数递归:

程序调用自身的编程技巧称为递归。一个过程或函数在其定义或说明中有直接或间接调用自身的一种方法,它通常把一个大型复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解,递归策略只需少量的程序就可描述出解题过程所需要的多次重复计算。

递归的两个必要条件:

1.存在限制条件,当满足这个限制条件的时候,递归便不再继续。

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

练习:接受一个整型值(无符号),按照顺序打印它的每一位。例如:输入:1234  输出:1 2 3 4

#include

void print(unsigned int n)

{

    if (n > 9)

    {

         print(n / 10);

    }

    printf("%d ", n % 10);

}

int main()

{

    unsigned int num = 0;

    scanf_s("%u", &num);    //unsigned是无符号类型

                            //递归--函数自己调用自己

    print(num);       //print函数可以打印参数部分数字的每一位

    return 0;

}

//如果用%d,输入的如果是负数,那么函数里的条件就不满足,%u是无符号,默认是正数

写递归代码的时候:1.不能死递归,都有跳出条件,每次递归要逼近跳出条件 2.递归层次不能太深

练习2:编写函数不允许创建临时变量,求字符串的长度。

代码答案1:(不允许创建临时变量,代码1使用了计数器count)

#include

#include

//strlen和sizeof的区别:strlen计算的是字符串到‘\0’位置的大小;sizeof计算的是字符串占的内存大小,功能是返回一个变量或者类型的大小(以字节为单位)

int my_strlen(char*str)    //数组传参,传首元素的地址

{

    int count = 0;

    while (*str != '\0')     //while可以一直循环到条件为真,if只能循环一次

    {

         count++;

         str++;

    }

    return count;

}

int main()

{

    char arr[] = "abc";

    //['a']['b']['c']['\0']

    //模拟实现一个strlen函数

    printf("%d\n", my_strlen(arr));

   

    return 0;

}

代码答案2:

int my_strlen(char*str)    //数组传参,传首元素的地址

{

    if (*str != '\0')

         return 1 + my_strlen(str + 1);

//str++后置++是先使用再++,传进去的是原来的值,留下来的是+后的值。前置++也不行,同样会让str本身发生变化,但str+1不会

    else

         return 0;

}

int main()

{

    char arr[] = "abc";

    //['a']['b']['c']['\0']

    //模拟实现一个strlen函数

    printf("%d\n", my_strlen(arr));

   

    return 0;

}


递归与迭代:

练习3:求n的阶乘(不考虑溢出)【阶乘就是1*2*3*4…*n】

迭代方法:

#include

int main()

{

    int n = 0;

    scanf_s("%d", &n);

    int i = 0;

    int ret = 1;

    //循环是一种迭代的方法

    for (i = 1; i <= n; i++)

    {

         ret = ret * i;

    }

    printf("%d\n", ret);

    return 0;

}

PS:迭代算法必须要有终止条件,以免陷入死循环。


递归方法:

int Fac(int n)

{

    if (n > 1)

         return n* Fac(n - 1);

    else

         return 1;

}

int main()

{

    int n = 0;

    scanf_s("%d", &n);

    int ret = Fac(n);

    printf("%d\n", ret);

    return 0;

}

练习:求第n个斐波那契数。(不考虑溢出)

注:斐波那契数:前两个数字相加。例:1 1 2 3 5 8 13 21 34 55……

int Fib(int n)

{

    if (n <=2)

         return 1;

    else

         return Fib(n - 1) + Fib(n - 2);

}

int main()

{

    int n = 0;

    scanf_s("%d", &n);

    int ret = Fib(n);

    printf("%d\n", ret);

    return 0;

}

但此函数有一定问题:

int count = 0;

             //递归可以求解,但是效率太低

int Fib(int n)

{

    //统计第三个斐波那契数的计算机次数

    if (n == 3)

         count++;

    if (n <=2)

         return 1;

    else

         return Fib(n - 1) + Fib(n - 2);

}

int main()

{

    int n = 0;

    scanf_s("%d", &n);

    int ret = Fib(n);

    printf("%d\n", ret);

    printf("count = %d\n", count);

    return 0;

}

//比如 如果计算50的斐波那契数会等很久的结果---效率太低且重复大量计算


所以修改如下:(迭代)

int Fib(int n)

{

    int a = 1;

    int b = 1;

    int c = 1;

    while (n > 2)

    {

         c = a + b;

         a = b;

         b = c;

         n--;      //这里不n--会死循环

    }

    return c;

}

int main()

{

    int n = 0;

    scanf_s("%d", &n);

    int ret = Fib(n);

    printf("%d\n", ret);

    return 0;

}

课外:汉诺塔研究、青蛙跳

你可能感兴趣的:(C语言,c++)