1.递归条件:
1).调用自己本身
2).有一个趋近于终止的条件(没有的话会栈溢出)
所有函数执行发生在栈(内存,特性:先进的后出)上
递归实现数组的逆置与输出:
a1.cpp
#include <stdio.h>
#include "a2.h" //自定义头文件
int main()
{ int arr[] = { 6, 5, 4, 3, 2, 1 };
Fun(arr, 0, sizeof(arr)/sizeof(int)); //计算数组长度
for (int i = 0; i < 6; i++)
{ printf("%-2d", arr[i]); }
printf("\n");
return 0;
}
a2.h
#ifndef _A_ //
#define _A_ //
void Fun(int arr[], int i, int j);
#endif //_A_防止头文件多次引入
a2.cpp
#include<stdio.h>
#include "a2.h"
void Fun(int arr[], int i, int j) //数组作为实参递给子函数时,递数组的首地址,无需定义指针
{ int x;
if (i = !j) //判断条件
{ x = arr[i];
arr[i] = arr[j];
arr[j] = x;
Fun(arr, i++, j++); //递归调用自身,不会释放之前的变量
}
}
2.汉诺塔递归(典例):
#include <stdio.h>
void move(int n, char x, char y, char z)
{
if (n == 1)
{
printf("%c -> %c\n",x,z);
}
else
{
move(n - 1, x,z,y);
printf("%c -> %c\n", x, z);
move(n - 1, y, x, z);
}
}
int main()
{
int n=10;
move(n,'x','y','z');
return 0;
}
3.青蛙跳台(非递归实现与递归调用):(‘斐波那契数列没有第一项’:1,2,3,5,8,13,21…)
#include<stdio.h>
#include<string.h>
int show1(int n) //非递归实现
{
int i, a = 1, b = 2, c;
if (n <= 3)
return n;
if (n > 3)
{
for (i = 3; i <= n; i++)
{
c = a;
a = b;
b = c + b;
}
return b;
}
}
int show2(int n) //递归调用
{
if (n <= 2) //限制条件
{
return n;
}
else
return show(n - 1) + show(n - 2);
}
int main()
{
int n = 0;
printf("请输入要计算的青蛙跳层数:\n");
scanf("%d",&n);
printf("青蛙跳方法有:%d种\n",show1(n)); //非递归实现
printf("青蛙跳方法有:%d种\n",show2(n)); //递归调用
return 0;
}
4.递归实现一个数的k次方与各各位数和:
#include<stdio.h>
int show1(int n)
{
if (n == 0)
return 0;
else
return (n % 10) + show1(n / 10); //相当于这个数除以10后比10的余数和,直到这个数各位比1小
}
int show2(int n, int k)
{
if (k == 1)
return n;
else
return n * show2(n, k - 1); //每项n都相当于n乘以n的(k-1)次幂
}
int main()
{
int n = 0, k = 0;
printf("请输入底数n和幂数k:\n");
scanf("%d%d", &n, &k);
printf("n的各位位数和为:%d\n", show1(n)); //各各位位数和
printf("n的k次方结果为:%d\n", show2(n, k)); //n的k次方
return 0;
}
5.不使用strlen函数(非递归实现与递归调用),计算字符串长度:
#include<stdio.h>
int Strlen1(char *str)
{
int len1 = 0;
while (*(str++) != '\0') //str为首地址str[0],不能使用++str或str=str+1
{
len1++; //未遇到终止符时长度+1
}
return len1;
}
int Strlen2(char str[])
{
if (*str == '\0') //限制条件
return 0;
return 1 + Strlen2(str + 1); //相当于第一个字符加终止符前剩余字符
}
int main()
{
char*a = "abcdefg";
int len1 = Strlen1("abcdefg");
int len2 = Strlen2(a);
printf("%d\n", len1);
printf("%d\n", len2);
return 0;
}
6.求一个数的阶乘(非递归实现与递归调用):
#include<stdio.h>
int Fac1(int num)
{
int i = 1;
for (num; num <= 0; num--)
i *= num; //循环至乘以1结束循环
return i;
}
int Fac2(int num)
{
if (num > 0)
return num * Fac2(num - 1); //相当于n乘以(n-1)的阶乘
else return 1; //当n=0时,开始‘归’
}
int main()
{
int n = 0;
printf("请输入一个数,求他的阶乘:\n");
scanf("%d", &n);
printf("%d\n", Fac1(n)); //非递归实现
printf("%d\n", Fac2(n)); //递归调用
return 0;
}
7.排列出一个数的各位位数:
#include <stdio.h>
void show(int n)
{
if (n > 9)
show(n / 10); //当n仅剩个位时,开始‘归’
printf("%-3d", n % 10); //先入后出,后递先归,所以不会先输出个位
}
int main()
{
int num = 0;
printf("请输入一个整数:\n");
scanf("%d", &num);
show(num);
printf("\n");
return 0;
}
8.递归实现输出逆置数组: (改变原数组与不改变原数组)
#include <stdio.h>
void Nizhi(int arr[], int i, int j) //数组作为实参递给子函数时,递数组的首地址,无需定义指针
{
int x;
if (i = !j) //限制条件
{
x = arr[i];
arr[i] = arr[j];
arr[j] = x;
Nizhi(arr, i++, j++); //递归调用自身,不会释放之前的变量
}
}
int reverse_string(char * string) //次子函数仅可以输出逆置数组但不改变原数组
{
if (*string != '\0')
{
string++;
reverse_string(string);
printf("%c", *(string - 1)); //递归逆向输出
}
return 0;
}
int main()
{
int arr[] = { 6, 5, 4, 3, 2, 1 };
char ch[100];
char* string = "abcdefghijklmnopqrstuvwxyz";
printf("请输入字符串:\n");
scanf("%s", ch);
Nizhi(arr, 0, sizeof(arr)/sizeof(int)); //计算数组长度
for (int i = 0; i < 6; i++) // 输出逆置数组验证
{
printf("%-2d", arr[i]);
}
printf("\n");
reverse_string(ch); //尽可以输出逆置数组但不改变原数组
printf("\n");
reverse_string(string); //尽可以输出逆置数组但不改变原数组
printf("\n");
return 0;
}