1. 程式人生 > >遞歸與非遞歸集錦篇

遞歸與非遞歸集錦篇

mov 相互 判斷 arr 一個數 char* 實現 使用遞歸 count

非遞歸也就是我們俗稱的循環,非遞歸代碼可能很長,但成本低(包括運行時間等)
遞歸也就是俗稱的自己調用自己,代碼或許很短,但成本高
兩種各有利弊,大多可以相互轉換,但有些情況,非一種不可
例題如下:

1.遞歸和非遞歸分別實現求第n個斐波那契數

#include<stdio.h>
int fib1(int n)//非遞歸
{
    int i;
    int f1 = 1;
    int f2 = 1;
    int f3 = 0;
    for (i = 2; i < n; i++)
    {
    //循環賦值
        f3 = f1 + f2;
        f1 = f2;
        f2 = f3;
    }
    return f3;
}
int fib2(n)//遞歸
{
    if (n <= 2)
    {
        return 1;
    }
    else
    {
        return fib2(n - 1) + fib2(n - 2);
    }
}
int main()
{
    int n=0;
    int ret1;
    int ret2;
    scanf("%d",&n);
    ret1 = fib1(n);
    printf("非遞歸=%d\n",ret1);
    ret2 = fib2(n);
    printf("遞歸=%d\n",ret2);
    return 0;
}

2.編寫一個函數實現n^k,使用遞歸實現

#include<stdio.h>

int fac(int n,int k)//遞歸
{
    if (0 == k)
        return 1;
    else if (1 == k)
        return n;
    else if (k > 1)
        return n*fac(n, k - 1);
    else
        return -1;
}
int main()
{
    int n, k;
    int ret;
    printf("輸入一個數字和需要計算的冪次:");
    scanf("%d%d",&n,&k);
    if (-1 == ret)
        printf("輸入錯誤!\n");
    else
        ret = fac(n, k);
        printf("%d",ret);
    return 0;
}

3.. 寫一個遞歸函數DigitSum(n),輸入一個非負整數,返回組成它的數字之和,例如,調用DigitSum(1729),則應該返回1 + 7 + 2 + 9,它的和是19

#include<stdio.h>
int DigitSum(int n)
{
    if (n < 10)
    {
        return n;
    }
    else
    {
        return DigitSum(n / 10) + n % 10;
    }
}
int main()
{
    int n,i=0;
    printf("請輸入一個非負整數:\n");
    scanf("%d",&n);
    int ret = DigitSum(n);
    printf("%d",ret);
    return 0;
}

4.遞歸和非遞歸分別實現strlen

#include<stdio.h>

int MyStrlen1(char arr[])//非遞歸//*str
{
    int i=0;
    while (arr[i]!=0)
    {
        i++;
    }
    return i;
}
int MyStrlen2(char arr[])//遞歸
{
    int i = 0;
    if (arr[i] != 0)//*str !=‘\0‘
        return 1 + MyStrlen2(arr+1);
    else
        return 0;
}
int main()
{
    char arr[] ="hello world!";//或者char *str="hello world!";
    int count1 = MyStrlen1(arr);//(str)
    printf("非遞歸=%d\n",count1);
    int count2 = MyStrlen2(arr);
    printf("遞歸=%d\n",count2);
    return 0;
}

5.遞歸和非遞歸分別實現求n的階乘

#include<stdio.h>

int Fac1(int n)//非遞歸
{
    int i;
    int sum = 1;
    if (0 == n)
        return 1;
    else
    {
        for (i = 1; i <= n; i++)
        {
            sum *= i;
        }
        return sum;
    }
}
int Fac2(int n)//遞歸
{
    if (0 == n)
        return 1;
    else 
        return n*Fac2(n - 1);
}
int main()
{
    int n,ret1;
    printf("請輸入需要階乘的整數:\n");
    scanf("%d",&n);
    if (n < 0)//提前判斷是否符合
    {
        printf("輸入錯誤!\n");
    }
    else
    {
        ret1 = Fac1(n);
        printf("非遞歸=%d\n", ret1);
        int ret2 = Fac2(n);
        printf("遞歸=%d\n", ret2);
    }
    return 0;
}

6.遞歸方式實現打印一個整數的每一位

#include <stdio.h>

void output(int x)
{
    if (x >= 10)
    {
        output(x / 10);  //x=x/10也對
    }
    printf("%d ", x % 10);

}
int main()
{
    int a;
    printf("請輸出一個數");
    scanf("%d", &a);
    output(a);
    return 0;
}

7.編寫一個函數 reverse_string(char * string)(遞歸和非遞歸實現)實現:將參數字符串中的字符反向排列。

#include<stdio.h>
#include<string.h>

void reverse_string1(char *p)
{
    int len = strlen(p);//字符串長度
    char tmp = *p;
    *p = *(p + len - 1);
    *(p + len - 1) = ‘\0‘;
    if (strlen(p + 1) > 1)
    {
        reverse_string1(p + 1);
    }
    *(p + len - 1) = tmp;
}
void reverse_string2(char* str)
{
    char *left = str;
    char *right = str + strlen(str) - 1;
    char temp;
    while (left <= right)
    {
        temp = *left;
        *left=*right;
        *right=temp;
        right--;
        left++;
    }
}
int main()
{
    char str[] = "hello world!";
    printf("初始化=%s\n", str);
    reverse_string1(str);
    printf("遞歸逆序=%s\n", str);
    reverse_string2(str);
    printf("非遞歸再逆序=%s\n",str);
    return 0;
}

8.漢諾塔問題(遞歸)

#include<stdio.h>
void move(char pos1, char pos2)//移動步驟函數
{
    printf("%c-->%c\n",pos1,pos2);
}
void Hanoi(int n, char pos1,char pos2,char pos3)
{
    if (n == 1)
    {
        move(pos1,pos3);//遞歸出口
    }
    else
    {
        Hanoi(n - 1, pos1, pos3, pos2);
        move(pos1,pos3);
        Hanoi(n-1,pos2,pos1,pos3);
    }
}
int main()
{
    int n;
    printf("請輸入漢諾塔盤子數:");
    scanf("%d\n",&n);
    Hanoi(n,‘A‘,‘B‘,‘C‘);
    return 0;
}

遞歸與非遞歸集錦篇