递归算法的设计方法:
适宜于用递归算法求解的问题的充分必要条件是:
(1)问题具有某种可借用的类同自身的子问题描述的性质
(2)某一有限步的子问题(也称作本原问题)有直接的解存在。
当一个问题存在上述两个基本要素时,设计该问题的递归算法的方法是:
(1)把对原问题的求解表示成对子问题求解的形式。
(2)设计递归出口。
阶乘:
import java.util.Scanner; public class JieChengDemo { public static long jieCheng(int num) { if(num==1) { return 1; } else { return num*jieCheng(num-1); //递归调用 } } public static void main(String[] args) { int num; long result; Scanner in = new Scanner(System.in); System.out.println("请输入一个正整数:"); num = in.nextInt(); result = JieChengDemo.jieCheng(num); System.out.println(num+"的阶乘是:"+result); } }
折半查找递归实现:
import java.util.Scanner; public class BinarySearch { public static boolean bSearch(int[] arr,int des,int low,int high) { int mid; //中间的下标 if(low > high) { return false; } mid = (low+high)/2; if(des == arr[mid]) { return true; } else if(des < arr[mid]) { return bSearch(arr,des,low,mid-1); //递归调用 } else { return bSearch(arr,des,mid+1,high); } } public static void main(String[] args) { // TODO Auto-generated method stub int[] arr = {1,6,11,17,23,45,56,76,87,93}; int des; Scanner in = new Scanner(System.in); System.out.println("请输入一个正整数(0-99):"); des = in.nextInt(); if(BinarySearch.bSearch(arr, des, 0, arr.length-1)) { System.out.println(des+"在数组当中!"); } else { System.out.println(des+"不在数组当中!"); } } }
斐波纳挈数列:
public class Bolienac { //获得波列那契数列第N项的值 public static int getNums(int n) { if(n==1||n==2) { return 1; } else { return getNums(n-1)+getNums(n-2); } } public static void main(String[] args) { //1,1,2,3,5,8,13 int n=7; int result=0; for(int i=n;i>=1;i--) { result+=Bolienac.getNums(i); } System.out.println("波列那契数列的前"+n+"项之和是:"+result); } }
求最大公约数:
public class GcbNumber { //求最大公约数的递归算法。 public static int gcb(int bigNum,int smallNum) { if(bigNum<0||smallNum<0) { return -1; //表示没有找到最大公约数。 } if(smallNum==0) { return bigNum; } if(bigNum < smallNum) { //这里也是函数套用的好方法 return gcb(smallNum,bigNum); } else { //这里是传进去大数除以小数取余数和小数 return gcb(smallNum,bigNum%smallNum); } } public static void main(String[] args) { int smallNum = 30; int bigNum = 25; int result = GcbNumber.gcb(bigNum, smallNum); if(result!=-1) { System.out.println(bigNum+"和"+smallNum+"的最大公约数是:"+result); } } }
递归过程和运行时栈:
递归函数的执行过程具有三个特点:
(1)函数名相同;
(2)不断地自调用;
(3)最后被调用的函数要最先被返回。
系统用于保存递归函数调用信息的堆栈称作运行时栈。
每一层递归调用所需保存的信息构成运行时栈的一个工作记录
栈顶的工作记录保存的是当前调用函数的信息,所以栈顶的工作记录也称为活动记录。
递归转为非递归算法:
一般来说,如下两种情况的递归算法可转化为非递归算法:
(1)存在不借助堆栈的循环结构的非递归算法,如阶乘计算问题、斐波那契数列的计算问题、折半查找问题等
(2)存在借助堆栈的循环结构的非递归算法。所有递归算法都可以借助堆栈转换成循环结构的非递归算法。
回溯法:也是递归算法中一个经典思想
回溯法的基本思想是:对一个包括有很多结点,每个结点有若干个搜索分支的问题,把原问题分解为对若干个子问题求解的算法。当搜索到某个结点、发现无法再继续搜索下去时,就让搜索过程回溯(即退回)到该结点的前一结点,继续搜索这个结点的其他尚未搜索过的分支;如果发现这个结点也无法再继续搜索下去时,就让搜索过程回溯到这个结点的前一结点继续这样的搜索过程;这样的搜索过程一直进行到搜索到问题的解或搜索完了全部可搜索分支没有解存在为止。
迷宫问题:
public class MyMaze { private static int startPosI;//入口的i下标 private static int startPosJ;//入口的j下标 private static int endPosI;//出口的i下标 private static int endPosJ;//出口的j下标 //设置迷宫入口的坐标 public void setStart(int startPosI,int startPosJ) { MyMaze.startPosI = startPosI; MyMaze.startPosJ = startPosJ; } //设置迷宫出口的坐标 public void setEnd(int endPosI,int endPosJ) { MyMaze.endPosI = endPosI; MyMaze.endPosJ = endPosJ; } //迷宫搜索通路的算法 /* cell:迷宫地图 * i: 入口的i坐标 * j: 入口的j坐标 **/ public static void visited(int[][] cell,int i,int j) { cell[i][j]=1; if(i==endPosI&&j==endPosJ) //找到了出口 { System.out.println("找到一条通路:"); for(int m=0;m<cell.length;m++) { for(int n=0;n<cell[0].length;n++) { if(cell[m][n]==2) { System.out.print("2"); } else if(cell[m][n]==1) { System.out.print("*"); } else { System.out.print(" "); } } System.out.println(); } }else{ //向左边寻找通路 if(cell[i][j-1]==0) { visited(cell,i,j-1); } //向右边寻找通路 if(cell[i][j+1]==0) { visited(cell,i,j+1); } //向上寻找通路 if(cell[i-1][j]==0) { visited(cell,i-1,j); } //向下寻找通路 if(cell[i+1][j]==0) { visited(cell,i+1,j); } } //下面的变0很关键,这一点很关键,是回溯法的本质,如果以上路都走不通,则把原来的路还原,上一层的函数 调用结束,上一层的函数则去寻找其他的路。每一次对的寻找都是不会把其置为0,一直到 最后一步打印完,之后 cell[i][j]=0; } public static void main(String[] args) { // TODO Auto-generated method stub //初始化一个迷宫地图 int[][] maze={ {2,2,2,2,2,2,2,2,2}, {2,0,0,0,0,0,0,0,2}, {2,0,2,2,0,2,2,0,2}, {2,0,2,0,0,2,0,0,2}, {2,0,2,0,2,0,2,0,2}, {2,0,0,0,0,0,2,0,2}, {2,2,0,2,2,0,2,2,2}, {2,0,0,0,0,0,0,0,2}, {2,2,2,2,2,2,2,2,2} }; MyMaze cell = new MyMaze(); cell.setStart(1, 1);//设置迷宫的入口坐标 cell.setEnd(7, 7);//设置迷宫的出口坐标 cell.visited(maze, 1, 1); } }
时间: 2024-10-06 03:34:02