程序设计与算法之递归基础篇与进阶篇(Java语言与C语言实现)

284 阅读4分钟

//递归小结:其实就是函数自己调用自己,都是父问题转换为子问题,循环一定可以改成递归。
//(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)) ;
}