//定义一个 ArrayStack 表示栈 class ArrayStack { private int maxSize; // 栈的大小 private int[] stack; // 数组,数组模拟栈,数据就放在该数组 private int top = -1;// top表示栈顶,初始化为-1 //构造器 public ArrayStack(int maxSize) { this.maxSize = maxSize; stack = new int[this.maxSize]; } //栈满 public boolean isFull() { return top == maxSize - 1; } //栈空 public boolean isEmpty() { return top == -1; } //入栈 public void push(int value) { //先判断栈是否满 if(isFull()) { System.out.println("栈满"); return; } top++; stack[top] = value; } //出栈 //将栈顶的数据返回 public int pop() { //先判断栈是否空 if(isEmpty()) { //抛出异常 throw new RuntimeException("栈空,没有数据~"); } int value = stack[top]; top--; return value; } //[遍历栈], 遍历时,须要从栈顶开始显示数据 public void list() { if(isEmpty()) { System.out.println("栈空,没有数据~~"); return; } //须要从栈顶开始显示数据 for(int i = top; i >= 0 ; i--) { System.out.printf("stack[%d]=%d\n", i, stack[i]); } }
测试:java
public static void main(String[] args) { //先建立一个arraystack对象表示栈 ArrayStack stack =new ArrayStack(4); String key= ""; boolean loop = true; Scanner scanner =new Scanner(System.in); while (loop){ System.out.println("show: 表示显示栈"); System.out.println("exit: 退出程序"); System.out.println("push: 表示添加数据到栈(入栈)"); System.out.println("pop: 表示从栈取出数据(出栈)"); System.out.println("请输入你的选择"); key = scanner.next(); switch (key) { case "show": stack.list(); break; case "push": System.out.println("请输入一个数"); int value = scanner.nextInt(); stack.push(value); break; case "pop": try { int res = stack.pop(); System.out.printf("出栈的数据是 %d\n", res); } catch (Exception e) { // TODO: handle exception System.out.println(e.getMessage()); } break; case "exit": scanner.close(); loop = false; break; default: break; } } System.out.println("程序退出了!"); }
简单的说: 递归就是方法自己调用本身,每次调用时传入不一样的变量.递归有助于编程者解决复杂的问题,同时可让代码变得简洁。程序员
递归调用机制算法
说明: 1)小球获得的路径,和程序员设置的找路策略有关即:找路的上下左右的顺序相关编程
2)再获得小球路径时,能够先使用(下右上左),再改为(上右下左),看看路径是不是有变化数组
/** * @author Sun.Mr * @create 2019-09-17 22:21 */ public class Migong { public static void main(String[] args) { //先建立一个二维数组,模拟迷宫 //地图 int[][] map = new int[8][7]; //使用1表示墙 //上下左右皆置位1 for (int i = 0; i < 7; i++) { map[0][i] = 1; map[7][i] = 1; } for (int i = 0; i < 8; i++) { map[i][0] = 1; map[i][6] = 1; } //设置挡板 map[3][1] = 1; map[3][2] = 1; //输出地图 System.out.println("地图的状况"); for (int i = 0; i < 7; i++) { for (int j = 0; j < 7; j++) { System.out.print(map[i][j] + " "); } System.out.println(); } //使用递归回溯给小球找路 setWay(map, 1, 1); //输出新的地图, 小球走过,并标识过的递归 System.out.println("小球走过,并标识过的 地图的状况"); for (int i = 0; i < 8; i++) { for (int j = 0; j < 7; j++) { System.out.print(map[i][j] + " "); } System.out.println(); } } //使用递归回溯给小球找路 //(1,1)----->(6,5) //4. 约定: 当map[i][j] 为 0 表示该点没有走过 当为 1 表示墙 ; 2 表示通路能够走 ; 3 表示该点已经走过,可是走不通 //5. 在走迷宫时,须要肯定一个策略(方法) 下->右->上->左 , 若是该点走不通,再回溯 /** * * @param map 表示地图 * @param i 从哪一个位置开始找 * @param j * @return 若是找到通路,就返回true,不然就返回false */ public static boolean setWay(int[][] map, int i, int j) { if(map[6][5] == 2) { // 通路已经找到ok return true; } else { if(map[i][j] == 0) { //若是当前这个点尚未走过 //按照策略 下->右->上->左 走 map[i][j] = 2; // 假定该点是能够走通. if(setWay(map, i+1, j)) {//向下走 return true; } else if (setWay(map, i, j+1)) { //向右走 return true; } else if (setWay(map, i-1, j)) { //向上 return true; } else if (setWay(map, i, j-1)){ // 向左走 return true; } else { //说明该点是走不通,是死路 map[i][j] = 3; return false; } } else { // 若是map[i][j] != 0 , 多是 1, 2, 3 return false; } } } }
八皇后问题,是一个古老而著名的问题,是回溯算法的典型案例。该问题是国际西洋棋棋手马克斯·贝瑟尔于1848年提出:在8×8格的国际象棋上摆放八个皇后,使其不能互相攻击,即:任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少种摆法。oop
八皇后问题算法思路分析测试
说明:理论上应该建立一个二维数组来表示棋盘,可是实际上能够经过算法,用一个一维数组便可解决问题. arr[8] = {0 , 4, 7, 5, 2, 6, 1, 3} //对应arr 下标 表示第几行,即第几个皇后,arr[i] = val , val 表示第i+1个皇后,放在第i+1行的第val+1列this
代码实现:google
package com.xtkj; /** * @author Sun.Mr * @create 2019-09-18 10:54 */ public class Queue8 { //定义一个max表示共有多少个皇后 int max = 8; //定义数组array, 保存皇后放置位置的结果,好比 arr = {0 , 4, 7, 5, 2, 6, 1, 3} int[] array = new int[max]; static int count = 0; public static void main(String[] args) { //测试一把 , 8皇后是否正确 Queue8 queue8 = new Queue8(); queue8.check(0); System.out.printf("一共有%d解法", count); } //编写一个方法,放置第n个皇后 public void check(int n){ if (n == max) { print(); return; } //依次放入皇后,并判断是否冲突 for(int i = 0; i < max; i++) { //先把当前这个皇后 n , 放到该行的第1列 array[n] = i; //判断当放置第n个皇后到i列时,是否冲突 if(judge(n)) { // 不冲突 //接着放n+1个皇后,即开始递归 check(n+1); // } //若是冲突,就继续执行 array[n] = i; 即将第n个皇后,放置在本行得 后移的一个位置 } } /** * 查看当咱们放置第n个皇后, 就去检测该皇后是否和前面已经摆放的皇后冲突 * @param n * @return */ private boolean judge(int n) { // 说明 //1. array[i] == array[n] 表示判断 第n个皇后是否和前面的n-1个皇后在同一列 //2. Math.abs(n-i) == Math.abs(array[n] - array[i]) 表示判断第n个皇后是否和第i皇后是否在同一斜线 // n = 1 放置第 2列 1 n = 1 array[1] = 1 // Math.abs(1-0) == 1 Math.abs(array[n] - array[i]) = Math.abs(1-0) = 1 //3. 判断是否在同一行, 没有必要,n 每次都在递增 for (int i = 0; i < n; i++) { // 说明 //1. array[i] == array[n] 表示判断 第n个皇后是否和前面的n-1个皇后在同一列 //2. Math.abs(n-i) == Math.abs(array[n] - array[i]) 表示判断第n个皇后是否和第i皇后是否在同一斜线 // n = 1 放置第 2列 1 n = 1 array[1] = 1 // Math.abs(1-0) == 1 Math.abs(array[n] - array[i]) = Math.abs(1-0) = 1 //3. 判断是否在同一行, 没有必要,n 每次都在递增 if (array[i] == array[n] || Math.abs(n - i) == Math.abs(array[n] - array[i])) { return false; } } return true; } private void print() { count++; for (int i = 0; i < array.length; i++) { System.out.print(array[i] + " "); } System.out.println(); } }