八十四.递归求解算法问题总结(查找与排序(一))——JAVA

查找与排序(二)
查找与排序(三)
查找与排序(四)

递归

递归设计经验:

  • 找重复(子问题)
    1.找到一种划分方法
    2.找到递推公式或者等价转换
    都是父问题转化为求解子问题
  • 找重复中的变化量→参数
  • 找参数变化趋势→设计出口
    根据参数变化的趋势,对边界进行控制,适时终止递归

一.切蛋糕思维:

例题1:求n的阶乘

import java.util.Scanner;

public class LianXi {
    
    
	public static int f(int n){
    
    
		if(n==1)
			return 1;
		return n * f(n-1);
	}
	
	public static void main(String[] args){
    
    
		Scanner in = new Scanner(System.in);
		int n = in.nextInt();
		System.out.println(f(n));
	}
}

例题2:打印 i 到 j

import java.util.Scanner;

public class LianXi {
    
    
	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 in = new Scanner(System.in);
		int i = in.nextInt();
		int j = in.nextInt();
		f(i,j);
	}
}

例题3:求数组中所有元素的和

import java.util.Scanner;

public class LianXi {
    
    
	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){
    
    
		Scanner in = new Scanner(System.in);
		int N = in.nextInt();
		int []arr = new int [N];
		for(int i=0; i<N; i++){
    
    
			arr[i] = in.nextInt();
		}
		int begin = in.nextInt();
		System.out.println(f(arr,begin));
	}
}

例题4:翻转字符串

import java.util.Scanner;

public class LianXi {
    
    
	public static String f(String s, int end){
    
    
		if(end==0)
			return "" + s.charAt(0);
		return s.charAt(end) + f(s,end-1);
	}
	
	public static void main(String[] args){
    
    
		Scanner in = new Scanner(System.in);
		String s = in.next();
		int end = s.length() - 1;
		System.out.println(f(s,end));
	}
}

二.划不开,有没有递推公式?有没有等价转换?

例题5:求斐波那契数列

斐波那契数列问题等价于两个子问题:
·求前一项
·求前二项
·两项求和

import java.util.Scanner;

public class LianXi {
    
    
	public static int f(int n){
    
    
		if(n==1 || n==2)
			return 1;
		return f(n-1) + f(n-2);
	}
	
	public static void main(String[] args){
    
    
		Scanner in = new Scanner(System.in);
		int n = in.nextInt();
		System.out.println(f(n));
	}
}

例题6:求最大公约数(辗转相除法)

import java.util.Scanner;

public class LianXi {
    
    
	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 in = new Scanner(System.in);
		int m = in.nextInt();
		int n = in.nextInt();
		System.out.println(gcd(m,n));
	}
}

例题7:递归形式进行插入排序

对数组0到倒数第一个元素进行排序:
等价于:
对数组的0到倒数第二个元素,这部分排序,然后把倒数第一个元素插入到这个有序的部分中。

import java.util.Scanner;

public class LianXi {
    
    
	public static void insertSort(int []arr, int k){
    
    
	//对数组0到k个元素进行排序
		if(k==0)
			return ;
		insertSort(arr,k-1);
		
	//将第k个元素插入到排序后的数组中
		int x = arr[k];
		int index = k-1;
		while(index>-1 && x<arr[index]){
    
    
			arr[index+1] = arr[index];
			index--;
		}
		arr[index+1] = x;
	}
	
	public static void main(String[] args){
    
    
		Scanner in = new Scanner(System.in);
		int N = in.nextInt();
		int []arr = new int [N];
		for(int i = 0; i<N; i++){
    
    
			arr[i] = in.nextInt();
		}
		System.out.println("初始数组为:");
		for(int i = 0; i<arr.length; i++){
    
    
			System.out.print(arr[i] + " ");
		}
		insertSort(arr,arr.length-1);
		System.out.println("\n" + "排序后:");
		for(int i = 0; i<arr.length; i++){
    
    
			System.out.print(arr[i] + " ");
		}
	}
}

在这里插入图片描述
例题8:汉诺塔问题
1~N从A移动到B,C作为辅助
等价于:
1、1~N-1从A移动到C,B为辅助
2、把N从A移动到B
3、1~N从C移动到B,A为辅助

import java.util.Scanner;

public class LianXi {
    
    
	public static void Han(int N, String from, String to, String help){
    
    
		if(N==1){
    
    
			System.out.println("move" + N + "from" + from + "to" + to);
			return ;
		}
		Han(N-1, from, help, to);
		System.out.println("move" + N + "from" + from + "to" + to);
		Han(N-1, help, to, from);
	}
	
	public static void main(String[] args){
    
    
		Scanner in = new Scanner(System.in);
		int N = in.nextInt();
		Han(N, "A", "B", "C");
	}
}

三.查找与排序

例题9:二分查找

全范围二分查找等价于三个子问题:
1、 左边找(递归)
2 、中间比
3、 右边找(递归)
注意:左查找和右查找只选其一

import java.util.Arrays;
import java.util.Scanner;

public class LianXi {
    
    
	public static int binarySearch(int []arr, int lo, int hi, int key){
    
    
		if(lo>hi)
			return -1;
		int mid = (lo + hi) / 2;
		if(arr[mid]<key){
    
    
			return binarySearch(arr, mid + 1, hi, key);
		}
		else if(arr[mid]>key){
    
    
			return binarySearch(arr, lo, mid - 1, key);
		}
		else{
    
    
			return mid;
		}
	}
	
	public static void main(String[] args){
    
    
		Scanner in = new Scanner(System.in);
		int N = in.nextInt();
		int []arr = new int[N];
		//数组元素赋值
		for(int i = 0; i<N; i++){
    
    
			arr[i] = in.nextInt();
		}
		
		//数组元素排序
		Arrays.sort(arr); 
		
		int key = in.nextInt();
		int t = binarySearch(arr, 0, arr.length - 1, key);
		if(t == -1)
			System.out.println("查找失败");
		else
			System.out.println("查找成功");
	}
}

例题10:查找与排序
1、二分查找与插入排序

import java.util.Scanner;

public class LianXi {
    
    
	
	//数组元素排序
	public static void insertSort(int []arr, int k){
    
    
	//对数组0到k个元素进行排序
		if(k==0)
			return ;
		insertSort(arr,k-1);
			
	//将第k个元素插入到排序后的数组中
		int x = arr[k];
		int index = k-1;
		while(index>-1 && x<arr[index]){
    
    
			arr[index+1] = arr[index];
			index--;
		}
		arr[index+1] = x;
	}
	
   //查找元素
	public static int binarySearch(int []arr, int lo, int hi, int key){
    
    
		if(lo>hi)
			return -1;
		int mid = (lo + hi) / 2;
		if(arr[mid]<key){
    
    
			return binarySearch(arr, mid + 1, hi, key);
		}
		else if(arr[mid]>key){
    
    
			return binarySearch(arr, lo, mid - 1, key);
		}
		else{
    
    
			return mid;
		}
	}
		
	public static void main(String[] args){
    
    
		Scanner in = new Scanner(System.in);
		int N = in.nextInt();
		int []arr = new int [N];
		for(int i = 0; i<N; i++){
    
    
			arr[i] = in.nextInt();
		}
		System.out.println("初始数组为:");
		for(int i = 0; i<arr.length; i++){
    
    
			System.out.print(arr[i] + " ");
		}
		insertSort(arr,arr.length-1);
		System.out.println("\n" + "排序后:");
		for(int i = 0; i<arr.length; i++){
    
    
			System.out.print(arr[i] + " ");
		}
		int key = in.nextInt();
		int t = binarySearch(arr, 0, arr.length - 1, key);
		if(t == -1)
			System.out.println("查找失败");
		else
			System.out.println("查找成功");
	}
}

在这里插入图片描述

2、希尔排序

把记录按下标的一定增量分组,对每组使用直接插入排序算法排序;随着增量逐渐减少,每组包含的关键词越来越多,当增量减至 1 时,整个文件恰被分成一组,算法便终止。
在这里插入图片描述

import java.util.Scanner;

public class LianXi {
    
    
	
	public static void shellSort(int []arr){
    
    
	         //设a为间隔
		for(int a = arr.length/2; a > 0; a = a / 2){
    
    
			for(int i = a; i < arr.length; i++){
    
    
				int x = arr[i];
				int index = i-a;
				while(index > -1 && x<arr[index]){
    
    
					arr[index+a] = arr[index];
					index -= a;
				}
				arr[index+a] = x;
			}
		}
	}
	
	public static void main(String[] args){
    
    
		Scanner in = new Scanner(System.in);
		int N = in.nextInt();
		int []arr = new int[N];
		for(int i = 0; i < N; i++){
    
    
			arr[i] = in.nextInt();
		}
		System.out.println("初始数组为:");
		for(int i = 0; i < arr.length; i++){
    
    
			System.out.print(arr[i] + " ");
		}
		System.out.println("\n");
		shellSort(arr);
		System.out.println("希尔排序后数组为:");
		for(int j = 0; j < arr.length; j++){
    
    
			System.out.print(arr[j] + " ");
		}
		
	}
}

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/JiangYu200015/article/details/113050011