递归算法:
1. 一切循环都可以写成递归
2. 数列的前一二项一般是递归出口
3. 递归函数先写递归出口,再else
斐波那契数列 Fibonacci Sequence
斐波那契数列 Fibonacci sequence 递归解法
序号:1 2 3 4 5 6 7 8 …
数列:1 1 2 3 5 8 13 21 …
表达式:
f
(
n
)
=
{
1
,
n
=1或2(递归出口)
3
n
+
1
,
其他
f(n) = \begin{cases} 1 , & \text{ $n$ =1或2(递归出口)} \\ 3n+1, & \text{ 其他} \end{cases}
f(n)={1,3n+1, n =1或2(递归出口) 其他
# include <stdio.h>
# include <stdlib.h>
int f(int n); // 递归函数
int main() {
int n = f(8);
printf("n = %d\n", n);
return 0;
}
int f(int n) {
if (n == 1) { // 先写递归出口
return 1;
} else if (n == 2) { // 先写递归出口
return 1;
} else {
return (f(n - 1) + f(n - 2));
}
}
for循环改递归
求前n项和
f
(
n
)
=
1
+
2
+
3
+
4
+
5
+
.
.
.
+
n
f(n)=1+2+3+4+5+...+n
f(n)=1+2+3+4+5+...+n
f
(
100
)
=
1
+
2
+
3
+
4
+
5
+
.
.
.
+
100
=
5050
f(100)=1+2+3+4+5+...+100=5050
f(100)=1+2+3+4+5+...+100=5050
# include <stdio.h>
# include <stdlib.h>
int f1(int n); // for循环
int f2(int n); // 递归 递归关系: f(n)=f(n-1)+n, 出口 f(1)=1
int main() {
int sum1, sum2, n;
printf("请输入n:\n");
scanf("%d", &n);
sum1 = f1(n);
printf("循环 sum = %d\n", sum1);
sum2 = f2(n);
printf("循环 sum = %d\n", sum2);
return 0;
}
int f1(int n) {
int s = 0;
int i;
for (i = 1; i <= n; i++) {
s += i;
}
return s;
}
int f2(int n) {
if (n == 1) { // 先写递归出口
return 1;
} else {
return (f2(n - 1) + n);
}
}
动态规划:
1. 从最后一个往前选
2. 每次有两个选择:选,不选
3. 一直倒着往前,第一个是出口
求数组的前n项和(递归写法)
求数组的前n项和
{
s
u
m
(
a
r
r
,
n
)
=
s
u
m
(
a
r
r
,
n
−
1
)
+
a
r
r
[
n
]
s
u
m
(
a
r
r
,
0
)
=
a
r
r
[
0
]
数组第一项,递归出口
\begin{cases} sum(arr,n) =sum(arr,n-1) + arr[n] \\ sum(arr,0) = arr[0] & \text{数组第一项,递归出口} \end{cases}
{sum(arr,n)=sum(arr,n−1)+arr[n]sum(arr,0)=arr[0]数组第一项,递归出口
# include <stdio.h>
# include <stdlib.h>
int sum(int arr[], int m); // 求数组的前 n 项和
int main() {
// 求数组的前n项
int arr[10] = {9, 8, 7, 6, 5, 4, 3, 2, 1};
int s = sum(arr, 8);
printf("s = %d\n", s);
return 0;
}
int sum(int arr[], int n) {
if (n == 0) { // 出口
return arr[0];
} else {
return sum(arr, n - 1) + arr[n];
}
}
求数组的前n项最大值(递归写法)
求数组的前n项最大值
{
m
a
x
(
a
r
r
,
n
)
=
m
a
x
(
m
a
x
(
a
r
r
,
n
−
1
)
,
a
r
r
[
n
]
)
m
a
x
(
a
r
r
,
0
)
=
a
r
r
[
0
]
数组第一项,递归出口
\begin{cases} max(arr,n)=max{( max(arr,n-1) , arr[n])}\\ max(arr,0) = arr[0] & \text{数组第一项,递归出口} \end{cases}
{max(arr,n)=max(max(arr,n−1),arr[n])max(arr,0)=arr[0]数组第一项,递归出口
# include <stdio.h>
# include <stdlib.h>
int max(int arr[], int m); // 求数组的前 n 项最大值
int main() {
// 求数组最大值
int l = max(arr, 8);
printf("max = %d\n", l);
return 0;
}
int max(int arr[], int n) {
if (n == 0) { // 出口
return arr[0];
} else {
if (max(arr, n - 1) > arr[n]) {
return max(arr, n - 1);
} else {
return arr[n];
}
}
}