递归与分治经典案例-Java实现
Posted nuist__NJUPT
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了递归与分治经典案例-Java实现相关的知识,希望对你有一定的参考价值。
1-阶乘问题
import java.util.Scanner;
public class Factorial {
public static int factorial(int n){
if(n == 0){
return 1 ;
}
return n * factorial(n-1) ;
}
public static void main(String[] args) {
Scanner input = new Scanner(System.in) ;
int n = input.nextInt() ;
System.out.println(factorial(n));
}
}
2-斐波那契数列
import java.util.Scanner;
public class Fibonacci {
public static int fibonacci(int n){
if(n == 1 || n == 2){
return 1 ;
}
return fibonacci(n-1) + fibonacci(n-2) ;
}
public static void main(String[] args) {
Scanner input = new Scanner(System.in) ;
int n = input.nextInt() ;
System.out.println(fibonacci(n));
}
}
3-汉诺塔
public class HanoiTower {
public static void hanoiTower(int n, String from, String to, String helper){
if(n == 1){ //当就一个盘子,则直接从A移动到B,同时退出递归
System.out.println("将第" + n + "个盘子从" + from + "移动到" + to );
return ;
}
hanoiTower(n-1, from, helper, to) ; //将n-1个盘子从A移动到C,B作为辅助
System.out.println("将第" + n + "个盘子从" + from + "移动到" + to); //将第n个盘子从A移动到B
hanoiTower(n-1, helper, to, from) ; //将n-1个盘子从C移动到B
}
public static void main(String[] args) {
hanoiTower(3, "A", "B", "C") ;
}
}
4-全排列
import java.util.Scanner;
public class FullPermutation {
public static int count = 0 ;
public static int f(int n){
if(n == 0){
return 1 ;
}
return n * f(n-1) ;
}
public static void fullPermutation(String prefix, char [] arr){
if(prefix.length() == arr.length){
System.out.println(prefix);
count ++ ;
if(count == f(arr.length)){ //count等于全排列的个数,则结束递归
System.exit(0);
}
}
for(int i=0; i<arr.length; i++){
char c = arr[i] ;
if(sum(prefix.toCharArray(), c) < sum(arr, c)) {//解决重复问题
fullPermutation(prefix + c, arr); //将当前字符串作为前缀继续递归下去
}
}
}
public static int sum(char [] arr, char c){
int count1 = 0 ;
for(int i=0; i<arr.length; i++){
if(arr[i] == c){
count1 ++ ;
}
}
return count1 ;
}
public static void main(String[] args) {
Scanner input = new Scanner(System.in) ;
String s = input.next() ;
fullPermutation("", s.toCharArray()) ;
}
}
5-二分查找
public class BinarySearch2 {
public static int binarySearch(int [] arr, int key, int low, int high){
int mid = (low + high) >>> 1 ;
if(low > high){
return -1 ;
}
if(arr[mid] > key){
return binarySearch(arr, key, low, high-1) ;
}else if(arr[mid] < key){
return binarySearch(arr, key, low+1, high) ;
}else{
return mid ;
}
}
public static void main(String[] args) {
int [] arr = new int []{1,3,5,6,8,9,10, 12, 28,50, 100} ;
System.out.println(binarySearch(arr, 10, 0, arr.length - 1));
System.out.println(binarySearch(arr, 7, 0, arr.length - 1));
}
}
6-棋盘覆盖
import java.util.Scanner;
/**
* 棋盘覆盖问题
* 在一个2的k次方 x 2的k次方个方格组成的棋盘中
* 恰有一个方格与其他方格不同,称该方格为一特殊方格,且称该棋盘为一特殊棋盘。在棋盘覆盖问题中,
* 要用图示的4种不同形态的L型骨牌覆盖给定的特殊棋盘上除特殊方格以外的所有方格,且任何2个L型骨牌不得重叠覆盖。
* Input
* k,dr,dc。k定义如前,dr,dc分别表示特殊方格所在的行号和列号 1= < k < =6
*
* Output
* 按照左上,右上,左下,右下的顺序用分治法求解。特殊方格标0,其他位置按上述顺序依次标记。
*/
public class ChessBoard {
public static int [][] board = new int [150][150] ; //不超过64
public static int tile = 0 ;
public static void chessBoard(int tr, int tc, int dr, int dc, int size){
if(size == 1){ //仅一个点,直接返回
return ;
}
int t = ++tile ; //L型骨牌编号
int s = size / 2 ;
//覆盖左上角的棋盘
if(tr+s>dr && tc+s>dc){ //特殊方格在左上角区域中
chessBoard(tr, tc, dr, dc, s) ;
}else{
//特殊方格不在左上角棋盘中,将特殊值填到右下角
board[tr+s-1][tc+s-1] = t ;
chessBoard(tr, tc, tr+s-1, tc+s-1, s) ;
}
//覆盖右上角的棋盘
if(tr+s>dr && tc+s<=dc){ //特殊方格在右上角区域
chessBoard(tr, tc+s, dr, dc, s) ;
}else{
board[tr+s-1][tc+s] = t ;
chessBoard(tr, tc+s, tr+s-1, tc+s, s) ;
}
//覆盖左下角的棋盘
if(tr+s<=dr && tc+s>dc){ //特殊方格在左下角区域
chessBoard(tr+s, tc, dr, dc, s) ;
}else{
board[tr+s][tc+s-1] = t ;
chessBoard(tr+s, tc, tr+s, tc+s-1, s) ;
}
//覆盖右下角
if(tr+s<=dr && tc+s <= dc){
chessBoard(tr+s, tc+s, dr, dc, s) ;
}else{
board[tr+s][tc+s]=t;
chessBoard(tr+s,tc+s,tr+s,tc+s,s);
}
}
public static void main(String[] args) {
Scanner input = new Scanner(System.in) ;
int k = input.nextInt() ;
int dr = input.nextInt() ; //特殊方格的行号
int dc = input.nextInt() ; //特殊方格的列号
int size = (int)Math.pow(2, k) ;
chessBoard(0, 0, dr, dc, size);
for(int i=0; i<size; i++){
for(int j=0; j<size; j++){
System.out.print(board[i][j] + " ");
}
System.out.println();
}
}
}
7-归并排序
public class MergeSort {
public static void mergeSort(int [] arr, int p,int r){
if(p < r){
int mid = (p + r) >>> 1 ;
mergeSort(arr, p, mid -1) ; //左侧归并排序
mergeSort(arr, mid+1, r) ; //右侧归并排序
merge(arr, p, r, mid) ; //合并
}
}
public static void merge(int [] arr, int p, int r, int mid){ //归并排序的重点在于归并
int [] helper = new int [arr.length] ;
for(int i=0; i<arr.length; i++){
helper[i] = arr[i] ;
}
int left = p ;
int right = mid + 1 ;
int current = p ;
while(left <= mid && right <=r){
if(helper[left] > helper[right]){
arr[current++] = helper[right++] ;
}else{
arr[current++] = helper[left++] ;
}
}
while(left <= mid){
arr[current++] = helper[left++] ;
}
while(right <= r){
arr[current++] = helper[right++] ;
}
}
public static void main(String[] args) {
int [] arr = new int [] {2,1,3,7,6,4,9,8,0} ;
mergeSort(arr, 0, arr.length-1);
for(int i=0; i<arr.length; i++){
System.out.print(arr[i] + " ");
}
}
}
8-快速排序
public class QuickSort {
public static void swap(int [] arr, int left, int right){
int temp = arr[left] ;
arr[left] = arr[right] ;
arr[right] = temp ;
}
public static int partition(int [] arr, int left, int right){
int pivot = arr[left] ; //初始化主元
int left1 = left + 1 ;
int right1 = right ;
while(left1 <= right1){
while(left1 <= right1 && arr[left1] <= pivot){
left1 ++ ;
}
while(left1 <= right1 && arr[right1] >= pivot){
right1 -- ;
}
if(left1 < right1) {
swap(arr, left1, right1);
}
}
swap(arr, left, right1) ;
return right1 ;
}
public static void quickSort(int [] arr, int left, int right){//先划分,再递归进行快速排序,重点在划分上
if(left < right){
int q = partition(arr, left, right) ;
quickSort(arr, left, q-1) ;
quickSort(arr, q+1, right) ;
}
}
public static void main(String[] args) {
int [] arr = new int [] {2,15,3,7,9,4,0递归思想