《数据结构》算法学习
作者:互联网
《数据结构》算法--递归与数学归纳法
递归与数学归纳法有着本质上的联系:
1.数列
数列也是一种特殊的数学归纳法,其递推公式、前n项求和都体现了数学归纳法和递归的
思想。
2.数学归纳法
步骤:(1)假设n = 1,结论成立;
(2)假设n = k时,结论成立,根据递推公式,求证n = k+1时结论也成立;
3.递归
步骤:(1)找递归出口,类似n = 1或初始化的状态;
(2) 找递归嵌套,同递推公式,找出第k项与第k-1项之间的关系;
(3)完成上面两步,再单纯考虑一个完整的算法周期的具体实现,后面的套娃让
程序自己去完成;
4.三者之间的关系如下表:
思想 | 初始状态 | 关系式 | 相互关系 |
---|---|---|---|
数列 | a1 = k,(k为已知数) | an = f(a(n-1)) | 数列首项为递归入口,递推公式为递归的函数调用 |
数学归纳法 | n=1时,结论成立 | 假设n=k时结论成立,证明n=k+1时结论也成立 | n=1为递归入口,k-->k+1的论证关系为递归的函数调用 |
递归 | 入口(一般元素个数为1) | 递归关系,函数一层层的调用 | 函数调用看作数列递推公式 |
5.示例
example 1:求数组的所有元素之和;
#include<stdio.h>
#include<stdlib.h>
//3.定义好递归出口和嵌套公式之后,整段函数只是单纯考虑一个完整的算法周期的实现:
// 即把sum分割成arr[L]与ArrSum[arr, L+1, R]之和,这边正确实现之后,后面的套娃让程序自己去完成;
// L为第一个元素位序,R为最后一个元素的位序;
int ArrSum(int arr[], int L, int R){
int sum;
//1.递归出口,如同数学归纳法中初始状态:n=1的情况;
if (L == R)
sum = arr[L];
else
//2.递归嵌套,同递推公式,找出L和L+1的关系
sum = arr[L] + ArrSum(arr, L+1, R);
return sum;
}
int main(){
int arr[5] = {5, 5, 5, 5, 10};
int s = ArrSum(arr, 0, 4);
printf("s = %d\n", s);
return 0;
}
example 2:求数组中所有元素的最大值;
#include<stdio.h>
#include<stdlib.h>
/*int FindMax(int arr[], int len){
int max = arr[0];
for (int i=0; i<len; i++){
if (arr[i] > max)
max = arr[i];
}
return max;
}*/
//3.两数比大小的具体实现,单纯考虑一个完整的算法周期的实现
// L为第一个元素位序,R为最后一个元素的位序;
int FindMax2(int arr[], int L, int R){
//1.递归出口
if (L == R)
return arr[L];
else{
int a = arr[L];
int b = FindMax2(arr, L+1, R);
//2.把套娃第二层当做一个整体,与a进行比较
if (a > b)
return a;
else
return b;
}
}
int main(){
int arr[10] = {5, 6, 10, 15, 10, 4, 23, 13, 8, 9};
int m;
m = FindMax2(arr, 0, 9);
printf("m = %d\n", m);
return 0;
}
example3:冒泡排序(从小到大);
//冒泡排序的递归实现:从小到大
#include<stdio.h>
#include<stdlib.h>
//3.两数比大小的具体实现
// L为第一个元素位序,R为最后一个元素的位序;
void Bubble(int arr[], int L, int R){
int temp;
//1.递归出口
if (L == R)
return;
else{
for (int i=L; i<=R-1; i++){
if (arr[i] > arr[i+1]){
temp = arr[i];
arr[i] = arr[i+1];
arr[i+1] = temp;
}
}
//2.进行完一个完整的比较周期(第一轮比较之后最大数在最右边)之后,
// 数组就被分成了Bubble(arr, L, R-1)和arr[R]两个部分
//3.把剩下的部分继续用递归实现
Bubble(arr, L, R-1);
}
return;
}
int main(){
int arr[10] = {5, 6, 11, 15, 10, 4, 23, 13, 8, 27};
Bubble(arr, 0, 9);
for (int i=0; i<10; i++)
printf("%d ", arr[i]);
printf("\n");
return 0;
}
example4:求两数的最大公约数(思想:辗转相除法)
//求两数的最大公约数(辗转相除法,若最后的余数为零则最后的被除数为最大公约数)
#include<stdio.h>
#include<stdlib.h>
int gcd(int a, int b){
int r = a % b;
/*两数相除:若余数为零,则被除数是最大公约数;
若余数不为零,则它们的最大公约数即是被除数与余数的最大公约数;*/
//递归出口
if (r == 0)
return b;
else
return gcd(b, r);
}
int main(){
int a, b;
scanf("%d", &a);
scanf("%d", &b);
int g = gcd(a, b);
printf("%d\n", g);
return 0;
}
标签:arr,include,return,递归,int,学习,算法,归纳法,数据结构 来源: https://blog.csdn.net/zcj_jarry/article/details/113097179