程序设计与算法之递归基础篇与进阶篇(C语言与Java语言实现)
//递归小结:其实就是函数自己调用自己,都是父问题转换为子问题,循环一定可以改成递归。
//(1)找重复:找到一种划分方法
//(2)找到递推公式或者等价转换
//(3)找到变换的量,作为参数
//(4)找出口
基础篇
C语言
1.递归实现计算n的阶乘.
#include <stdio.h>
//递归实现n的阶乘
int f(int n){
if(n==1){
return 1 ;
}
return n*f(n-1);
}
int main(){
int num ;
scanf("%d",&num);
printf("%d",f(num)) ;
}
2.递归实现打印i到j的值 。
#include <stdio.h>
//递归实现打印i到j的值
void f(int i, int j){
if(i>j)
return ;
printf("%d ",i) ;
f(i+1,j) ;
}
int main(){
int num1, num2 ;
scanf("%d",&num1);
scanf("%d",&num2) ;
f(num1,num2) ;
}
3.递归求数组中某个下标开始后的值之和.
#include <stdio.h>
//递归求数组中某个下标开始后的值之和
int Sum(int arr[], int begin, int n){
if(begin == n-1){
return arr[begin] ;
}
return arr[begin] + Sum(arr,begin+1,n) ;
}
int main(){
int arr[] = {1,2,3,4,5} ;
int length = sizeof(arr) / sizeof(int) ;
printf("%d",Sum(arr,0,length)) ;
}
4.递归实现字符串翻转.
#include <stdio.h>
//递归实现字符串翻转
void Reverse(char s[], int end){
if(end==0){
printf("%c",s[end]) ;
}
if(end<1){
return ;
}
printf("%c",s[end]) ;
Reverse(s,end-1) ;
}
int main(){
char arr[3] ;
scanf("%s",&arr) ;
int length = strlen(arr) ;
Reverse(arr,length);
}
5.递归实现斐波那契数列第n项.
#include <stdio.h>
//递归实现斐波那契数列第n项
int f(int n){
if(n==1 || n==2){
return 1 ;
}
return f(n-1) + f(n-2) ;
}
int main(){
int n ;
scanf("%d",&n) ;
printf("%d",f(n)) ;
}
6.用递归求两个数的最大公约数.
#include <stdio.h>
int gcd(int m, int n){
if(n==0){
return m ;
}
return gcd(n,m%n) ;
}
int main(){
//用递归求两个数的最大公约数
int num1, num2 ;
scanf("%d%d",&num1,&num2) ;
printf("%d",gcd(num1,num2)) ;
}
7.用递归求两个数的最小公倍数 .
#include <stdio.h>
int gcd(int m, int n){
if(n==0){
return m ;
}
return gcd(n,m%n) ;
}
int main(){
//用递归求两个数的最小公倍数
int num1, num2 ;
scanf("%d%d",&num1,&num2) ;
printf("%d",num1*num2/gcd(num1,num2)) ;
}
8.二分查找的递归解法,类似于剪枝.
#include<stdio.h>
int BS(int arr[], int low, int high, int key){
int mid = (low + high) / 2 ;
if(key > arr[mid]){
return BS(arr,mid+1,high,key) ;
}
else if(key < arr[mid]){
return BS(arr,low,mid-1,key) ;
}
else{
return mid ;
}
}
int main(){
int arr[] = {1,2,3,4,5,6,7,8,9} ;
printf("%d\n",BS(arr,0,8,4)) ;
}
Java语言
1.递归实现n的阶乘.
import java.util.Scanner;
//递归实现n的阶乘
public class R1 {
public static int f(int n) {
if(n == 1) {
return 1 ;
}
return n * f(n-1) ;
}
public static void main(String[] args) {
Scanner input = new Scanner(System.in) ;
int num = input.nextInt();
System.out.println(f(num)) ;
}
}
2.递归实现打印i到j的值.
import java.util.Scanner ;
public class R2 {
//递归打印i到j的值
public static void f(int i, int j) {
if(i>j) {
return ;
}
System.out.println(i);
f(i+1,j) ;
}
public static void main(String[] args) {
Scanner input =new Scanner(System.in) ;
int i = input.nextInt();
int j = input.nextInt();
f(i,j) ;
}
}
3.递归实现求数组中某个下标开始后的值之和.
//求数组中某个下标开始后的值之和
public class R3 {
public static int f(int arr[], int begin) {
if(begin == arr.length-1) {
return arr[begin] ;
}
return arr[begin] + f(arr,begin+1) ;
}
public static void main(String[] args) {
int num[] = {1,2,3,4,5} ;
System.out.println(f(num,0));
}
}
4.递归实现字符串翻转.
//递归实现字符串翻转
import java.util.Scanner ;
public class R4 {
public static String Reverse(String s, int end) {
if(end == 0) {
return "" + s.charAt(end) ;
}
return s.charAt(end) + Reverse(s,end-1) ;
}
public static void main(String[] args) {
Scanner input = new Scanner(System.in) ;
String s = input.next();
System.out.println(Reverse(s,s.length()-1));
}
}
5.递归求第n项的斐波那契数列,求前n项斐波那契数列之和.
//递归求第n项的斐波那契数列
//求前n项斐波那契数列之和
//注:递归可能分解成常量+小规模,也可能分解成几个小规模之和
import java.util.Scanner ;
public class R5 {
public static int f(int n) {
if(n==1 || n==2) {
return 1 ;
}
return f(n-1) + f(n-2);
}
public static int f2(int n) {
int sum = 0;
for(int i=1; i<=n; i++) {
sum += f(i) ;
}
return sum ;
}
public static void main(String[] args) {
Scanner input = new Scanner(System.in) ;
int n = input.nextInt();
System.out.println(f(n));
System.out.println(f2(n)) ;
}
}
6.用递归求最大公约数.
//用递归求最大公约数
//可以找递推公式或等价转换
import java.util.Scanner; ;
public class R6 {
public static int gcd(int m, int n) {
if (n == 0) {
return m ;
}
return gcd(n,m%n) ;
}
public static void main(String[] args) {
Scanner input = new Scanner(System.in) ;
int num1 = input.nextInt();
int num2 = input.nextInt();
System.out.println(gcd(num1,num2));
}
}
7.用递归求最小公倍数.
import java.util.Scanner; ;
public class R6 {
public static int gcd(int m, int n) {
if (n == 0) {
return m ;
}
return gcd(n,m%n) ;
}
public static void main(String[] args) {
Scanner input = new Scanner(System.in) ;
int num1 = input.nextInt();
int num2 = input.nextInt();
System.out.println(num1*num2/gcd(num1,num2));
}
}
8.二分查找的递归解法,类似于剪枝.
public class R8 {
public static int BS(int arr[], int low, int high, int key) {
if(low > high) { //未找到关键字的位置
return -1 ;
}
int mid = (low + key) / 2 ;
if(key > arr[mid]) {
return BS(arr,mid+1,high,key) ;
}
else if(key < arr[mid]) {
return BS(arr,low,mid-1,key) ;
}
else
return mid ; //找到关键字的位置
}
public static void main(String[] args) {
int arr[] = {1,2,3,4,5,6,7,8} ;
System.out.print(BS(arr,0,8,5)) ;
}
}
进阶篇
Java语言
1.小白上楼梯(递归设计):小白正在上楼梯,楼梯有n阶,小白一次只能上1阶,2阶和3阶,计算小白有多少种上楼梯的方式?
import java.util.Scanner ;
public class R9 {
//到n阶层楼梯的方式等于到倒数第二次所在楼梯的方式之和
//公式如下:f(n)=f(n-1)+f(n-2)+f(n-3)
public static int f(int n) {
if(n == 1) {
return 1 ;
}
if(n == 2) {
return 2;
}
if(n == 3) {
return 4 ;
}
return f(n-1) + f(n-2) + f(n-3) ;
}
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
int n = input.nextInt() ;
System.out.println(f(n));
}
}
2.有个由小到大排序后的字符串数组,其中散布着一些空字符串,找出给定字符串的索引。注:给定字符串肯定不是空字符串.
public class R10 {
//有个由小到大排序后的字符串数组,其中散布着一些空字符串,找出给定字符串的索引。
//注:给定字符串肯定不是空字符串
public static int f(String arr[], String p) {
int begin = 0 ;
int end = arr.length - 1;
while(begin <= end) {
int mid = begin + ((end - begin)>>1) ;
while(arr[mid].equals("")) {//中间位置为空串
mid ++ ;
if(mid >end) { //注意判断:若中间位置大于结束则没找到
return -1 ;
}
}
if(arr[mid].compareTo(p)>0) {//中间位置字符大于给定字符
end = mid - 1 ;
}
else if (arr[mid].compareTo(p)<0) {//中间位置字符小于给定字符
begin = mid + 1 ;
}
else { //中间位置等给定字符
return mid ;
}
}
return -1 ;
}
public static void main(String[] args) {
String s[] = {"a","","ac","","ad","b","","ba"} ;
System.out.println(f(s,"abc"));
}
}
3.求最长连续递增序列.
如:{1,9,2,5,7,3,4,6,8,0}中的最长连续递增序列为:{3,4,6,8} 注:这题没用递归.
//最长连续递增序列
//如:{1,9,2,5,7,3,4,6,8,0}中的最长连续递增序列为:{3,4,6,8}
public class R11 {
public static void f(int arr[]) {
int begin = 0 ;
int end = 0 ;
int count = 0, flag = 0 ;
int first = 0 ,eventually = 0;
while( end<arr.length-1) {
if(arr[end+1]>arr[end]) {
end ++ ;
count ++ ;
}
else {
if(count>flag) {
flag = count ;
first = begin ;
eventually = end ;
end ++ ;
begin = end ;
}
}
}
for(int i=first; i<=eventually; i++) {
System.out.print(arr[i]+ " ") ;
}
}
public static void main(String[] args) {
int arr[] = {1,9,2,5,7,3,4,6,8,0} ;
f(arr) ;
}
}
4.设计一个递归算法的求a的n次幂的方法.
//设计一个递归算法的求a的n次幂的方法
import java.util.Scanner ;
public class R12 {
public static int pow(int a, int n) {
int res = a, ex = 1 ;
if(n==0) { //出口
return 1 ;
}
while(ex*2 <= n) {
res *= res ;
ex *= 2 ;
}
//还有n-ex个未乘到结果里面,递归求
return res * pow(a,n-ex) ;
}
public static void main(String[] args) {
Scanner input = new Scanner(System.in) ;
int a = input.nextInt();
int n = input.nextInt();
System.out.println(pow(a,n));
}
}
C语言
1.小白上楼梯(递归设计):小白正在上楼梯,楼梯有n阶,小白一次只能上1阶,2阶和3阶,计算小白有多少种上楼梯的方式?
#include<stdio.h>
int f(int n){
if(n==1){
return 1 ;
}
if(n==2){
return 2 ;
}
if(n==3){
return 4 ;
}
return f(n-1) + f(n-2) + f(n-3) ;
}
int main(){
int n ;
scanf("%d",&n) ;
printf("%d",f(n)) ;
}
2.有个由小到大排序后的字符串数组,其中散布着一些空字符串,找出给定字符串的索引。注:给定字符串肯定不是空字符串.
#include<stdio.h>
int f(char arr[],char p){
int begin = 0 ;
int end = 7 ;
int mid ;
while(begin <= end){
mid = (begin + end) / 2 ;
while(arr[mid] == ' '){
mid ++ ;
if(mid > end){
return -1 ;
}
}
if(arr[mid] < p){
begin = mid + 1 ;
}
else if(arr[mid] > p){
end = mid - 1 ;
}
else{
return mid ;
}
}
return -1 ;
}
int main(){
char s[] = {'a',' ','ac',' ','ad','ae',' ','afg'} ;
printf("%d\n",f(s,'ac')) ;
}
3.求最长连续递增序列.
如:{1,9,2,5,7,3,4,6,8,0}中的最长连续递增序列为:{3,4,6,8} 注:这题没用递归.
#include<stdio.h>
void f(int arr[],int length){
int i, begin = 0, end = 0, count =0, flag = 0 ;
int first=0, eventually=0;
while(end < length-1){
if(arr[end+1] > arr[end]){
end ++ ;
count++ ;
}
else{
if(count > flag){
flag = count ;
first = begin ;
eventually = end ;
end ++ ;
begin = end ;
count = 0 ;
}
}
}
for(i=first;i<=eventually;i++){
printf("%d ",arr[i]) ;
}
}
int main(){
int arr[] = {1,9,2,5,7,3,4,6,8,0} ;
int length = sizeof(arr) / sizeof(int) ;
f(arr,length) ;
}
4.设计一个递归算法的求a的n次幂的方法.
#include<stdio.h>
int pow(int a, int n){
int ex = 1 ;
int result = a ;
if(n == 0){
return 1 ;
}
while(ex * 2 <= n){
ex *= 2 ;
result *= result ;
}
return result * pow(a,n-ex) ;//把剩余n-ex个乘到结果里面
}
int main(){
int a, n ;
scanf("%d%d",&a,&n) ;
printf("%d\n",pow(a,n)) ;
}