一.递归函数的设计
递归函数的设计主要是三步:
1.给定该函数一个明确的语义
2.实现边界条件时的程序逻辑
3.假设递归函数调用返回值正确,实现本层函数逻辑
其中,最重要的是第一步,下面看几个例子来感受递归函数的设计
二.例题
一.路飞吃桃
#include <stdio.h>
int f(int x){
if(x == 1) return 1;
return (f(x - 1) + 1) * 2;
}
int main() {
int n;
scanf("%d", &n);
printf("%d", f(n));
return 0;
}
二.弹簧板
#include <stdio.h>
#define max_n 100000
int f(int i, int *p, int n){
if(i >= n) return 0;
return f(i + p[i], p, n) + 1;
}
int main() {
int n, cnt = 0;
scanf("%d", &n);
int arr[max_n + 5];
for(int i = 0; i < n; i++){
scanf("%d", &arr[i]);
}
printf("%d", f(0, arr, n));
return 0;
}
三.递归实现指数型枚举
#include <stdio.h>
void printf_one_result(int x, int *p){
for(int i = 0; i <= x; i++){
if(i) printf(" ");
printf("%d", p[i]);
}
printf("\n");
return ;
}
void f(int i, int j, int x, int *p){ //求从下标为i的位置开始的指数型枚举,j表示当前位置所能枚举的最小值,x表示枚举上限,p指针指向存数据的数组
if(j > x) return ;//当j为上限时,i位置就不能继续向后枚举
for(int k = j; k <= x; k++){
p[i] = k;
printf_one_result(i, p);//当i位置存k时,输出从0到i的数据
f(i + 1, k + 1, x, p);//利用递归,进行i+1位置的指数型枚举
}
return ;
}
//核心思想就是枚举每个位置所能取得值,前提条件时由其前一个位置的值提供
int main() {
int n;
scanf("%d", &n);
int arr[10];
f(0, 1, n, arr);
return 0;
}
四.递归实现组合型枚举
#include <stdio.h>
void printf_one_result(int m, int *p) {
for(int i = 0; i < m; i++){
if(i) printf(" ");
printf("%d", p[i]);
}
printf("\n");
return ;
}
void f(int i, int j, int n, int m, int *p){
if(i == m){
printf_one_result(m, p);
return ;
}
for(int k = j; k <= n && m - i - 1 <= n - k; k++){
p[i] = k;
f(i + 1, k + 1, n, m, p);
}
return ;
}
//组合数枚举
int main() {
int n, m;
scanf("%d%d", &n, &m);
int arr[10];
f(0, 1, n, m, arr);
return 0;
}
五.递归实现排列型枚举
#include <stdio.h>
void printf_one_result(int *p1, int n){
for(int i = 0; i < n; i++){
if(i) printf(" ");
printf("%d", p1[i]);
}
printf("\n");
return ;
}
void f(int i, int n, int *p1, int *p2){
if(i == n){
printf_one_result(p1, n);
return ;
}
for(int k = 1; k <= n; k++){
if(p2[k]) continue;
p1[i] = k;
p2[k] = 1;
f(i + 1, n, p1, p2);
p2[k] = 0; //当程序枚举完i+1位之后的排列后,回溯到本层循环时,将当前位置的k回收
}
return ;
}
int main() {
int n;
scanf("%d", &n);
int arr[10], flag[10] = {0};
f(0, n, arr, flag);
return 0;
}