写递归函数的核心思想:
1找到函数关系: f(n) = f(n-1) + 2
2找到出口: f(1) =1
递归数列
f(n) = f(n-1) + 2
f(1) =1
1 3 5 7 9
先写递归出口
#include<stdio.h>
#include<windows.h>
int f(int n) {
if(n == 1) {
return 1;
}
else {
return f(n-1)+2;
}
}
int main() {
int num = f(6);
printf("num = %d\n",num);
Sleep(10000);
}
// 1 3 5 7 9 11
斐波那契数列 Fibonacci
1 1 2 3 5 8 13 31
#include<stdio.h>
#include<windows.h>
int f(int n) {
if(n == 1) {
return 1;
}
else if(n ==2) {
return 1;
}
else {
return (f(n-1)+f(n-2));
}
}
int main() {
int num = f(6);
printf("num = %d\n",num);
Sleep(10000);
}
// 1 1 2 3 5 8 13 31
// 1 2 3 4 5 6 7 8
所有循环都可以用递归来表示
求sum:1加到100的和
1.找出来公式 f(n) = f(n-1) + n
2.找到出口 f(1) =1
1+2+3...+100
#include<stdio.h>
#include<windows.h>
int sum(int n) {
if(n == 1) {
return 1;
}
else {
return (sum(n-1)+n);
}
}
int main() {
int num = sum(100);
printf("num = %d\n",num);
Sleep(10000);
}
// 应该得到5050
int arr[] = {1,7,8,6,4,7,3}
求数组的前n项和,
1 下面是递归关系
sum(arr,n) = sum(arr,n-1) + arr[n]
2 递归出口是 sum(arr,0) = arr[0]
#include<stdio.h>
#include<windows.h>
int sum(int arr[], int n) {
if(n == 0) {
return arr[0];
}
else {
return (sum(arr, n-1) + arr[n]); // 这里需要写arr,而不是arr[]
}
}
int main() {
int arr[9] = {9,8,7,6,5,4,3,2,1}; // 9个数
int num = sum(arr, 8); // 这里需要写arr,而不是arr[].需要写8而不是9,第八个数是1
printf("num = %d\n",num);
Sleep(10000);
return 0;
}
// 得45
求数组前n项的最大值
1 关系:如果数组前n-1项的最大值>第n项, 最大值为arr[n],否则最大值是maxnum(arr, n-1)
2 递归出口:如果数组arr只有一项,则是这一项arr[0]
#include<stdio.h>
#include<windows.h>
int maxnum(int arr[], int n) {
if (n == 0) {
return arr[0];
}
else if (maxnum(arr, n-1) > arr[n]) {
return maxnum(arr, n-1);
}
else {
return arr[n];
}
}
int main() {
int arr[9] ={1,2,6,8,9,4,3,5,7};
printf("maxnum(8)=%d\n", maxnum(arr, 2));
Sleep(10000);
return 0;
}
递归练习题
循环都能写成递归,递归不一定都能写成循环
问题1:给出一个数组一共10个数,求其中最大数值
arr[10] = {8,2,3,4,6,5,1,10,9,7};
--非递归写法--
循环loop
#include<stdio.h>
#include<windows.h>
#include<string.h>
int findMax(int arr[], int n) {
int max = arr[0];
int i;
for(i = 0; i <10; i++) {
if(arr[i] > max) {
max = arr[i];
}
}
return max;
}
int main() {
int arr[10] = {8,2,3,4,6,5,1,10,9,7};
int max = findMax(arr, 10);
printf("max is %d", max);
Sleep(10000);
return 0;
}
--递归写法--
int findMax(int arr[], int L,int R)
arr[L]与findMax(arr,L+1,R)做对比
--递归--
#include<stdio.h>
#include<windows.h>
#include<string.h>
int findMax(int arr[], int L,int R) {
if(L==R) {
return arr[L];
}
else {
int a = arr[L];
int b = findMax(arr, L+1, R);
if (a > b) {
return a;
}
else {
return b;
}
}
}
int main() {
int arr[10] = {8,2,3,4,6,5,1,10,9,7};
int max = findMax(arr, 0, 9);
printf("max is %d", max);
Sleep(10000);
return 0;
}
问题2:数组求和,求L到R所有数字的和
arr[10] = {8,2,3,4,6,5,1,10,9,7};
递归关系:sum = arr[L] + SUM(arr, L+1, R);
#include<stdio.h>
#include<windows.h>
#include<string.h>
int SUM(int arr[], int L,int R) {
int sum;
if(L==R) {
return arr[L];
}
else if(L > R) {
printf("输入错误!!!");
}
else {
sum = arr[L] + SUM(arr, L+1, R);
return sum;
}
}
int main() {
int arr[10] = {8,2,3,4,6,5,1,10,9,7};
int sum = SUM(arr, 2, 4);
printf("sum is %d", sum);
Sleep(10000);
return 0;
}
问题3:冒泡排序,从小到大排顺
第一次冒泡(0,5)
前5个没排序,需要再次冒泡(0,4)
#include<stdio.h>
#include<windows.h>
#include<string.h>
int bubble(int arr[], int L,int R) {
if (L==R) {
//
}
else {
int i;
for (i = L; i < R; i++) {
if(arr[i]>arr[i+1]) {
int tmp = arr[i];
arr[i] = arr[i+1];
arr[i+1] = tmp;
}
}
bubble(arr, L, R-1);
}
}
int main() {
int i;
int arr[10] = {8,2,3,4,6,5,1,10,9,7};
bubble(arr, 0, 9);
for (i=0; i<9; i++) {
printf("%d ", arr[i]);
}
Sleep(10000);
return 0;
}
这里需要注意一个问题
//正确写法
int arr[10] = {8,2,3,4,6,5,1,10,9,7};
bubble(arr, 0, 9);
int i; // int i写在后面会报错,这种类型声明需要放在前面!
//错误写法
int i; // 这样就对了!
int arr[10] = {8,2,3,4,6,5,1,10,9,7};
bubble(arr, 0, 9);
问题3:求两个数的最大公约数
a = 72
b = 56
发现规律,如果r=0,b就是最大公约数
#include<stdio.h>
#include<windows.h>
#include<string.h>
int gcd(int a, int b) {
int r = a % b;
if(r == 0) {
return b;
}
else {
return gcd(b, r);
}
}
int main() {
int x, y;
int g;
printf("请输入第一个数:\n"); // 不用考虑数的大小
scanf("%d",&x);
printf("请输入第二个数:\n");
scanf("%d",&y);
g = gcd(x,y);
printf("公约数为:%d\n", g);
Sleep(10000);
return 0;
}