回顾总结5
递归
自己调用自己
迷宫问题实例
思路
- 先创建迷宫,用二维数组表示,int[] [] map = new int[8] [7];
- 规定map数组中的元素值,0表示能走,1表示障碍物
- 设置障碍物
- 写递归方法,参数为map数组地图和初始位置(i,j)
- 递归方法
- 外层判断,是否找到终点,是就返回true
- 不是的话,判断当前位置是否通路,是就标记走过
- 判断下一个位置,递归,重复所有步骤。
public class Test {
public static void main(String[] args) {
//定义一个迷宫大小的二维数组
int[][] map = new int[8][7];
//设置障碍物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;
T t = new T();
t.findWay(map,1,1);
for (int i = 0; i < map.length; i++) {
for (int j = 0; j < map[i].length; j++) {
System.out.print(map[i][j]+" ");
}
System.out.println();
}
}
}
//递归所在的类。写递归方法
class T {
//找迷宫只有两种结果,所以返回值选择布尔类型
//参数有,迷宫的二维数组,当前的位置i和j
public boolean findWay(int[][] map , int i , int j) {
if(map[6][5] == 2){
//这是一个返回值为布尔的方法
//(6,5)是终点,如果把终点设置为2了,代表已经到终点了。退出循环,返回true
return true;
}else{
if(map[i][j] == 0){
//判断当前位置,是否能走,可以走就置为2,然后去下一个位置去判断
map[i][j] = 2;
//判断下一个位置,优先顺序为下右上左,不存在下一步就置为3.死路
if(findWay(map,i+1, j)){
return true;
}else if(findWay(map, i, j+1)){
return true;
}else if(findWay(map, i-1, j)){
return true;
}else if(findWay(map, i, j-1)){
return true;
}else{
map[i][j] = 3;
return false;
}
}else{
//map[i][j] = 1,2,3。不能走,返回false
return false;
}
}
}
}
八皇后实例
思路分析
- 定义一维数组,下标表示行,值表示列
- 定义一个方法用来传递皇后的个数和建立数组
- 定义一个方法用来遍历值是否合法
- 定义一个方法对合法的判定
public class Queen {
public static void main(String[] args) {
Test test = new Test();
test.queen(8);
System.out.println(test.count);
}
}
class Test {
int[] arr;//定义一个数组,存放(8)皇后的数据
int count = 0;//用来计数符合(8)皇后的数量
int currentRow = 0;//数组的当前行
public void queen(int n) {//传递是几皇后
arr = new int[n];//建立一维数组
check(n, currentRow);//传递一维数组的大小和一个定位当前数组行的变量
}
public void check(int n, int currentRow) {//检查所有符合条件的八皇后
if (n == currentRow) {//如果当前行等于数组长度,说明所有行已经遍历完,得到一个八皇后
for (int i = 0; i < arr.length; i++) {//将数组中的八皇后输出出来
System.out.print(arr[i] + " ");
}
System.out.println();
count++;//符合条件的八皇后数量+1
} else {//还在遍历,判断皇后位置
for (int i = 0; i < n; i++) {//八皇后是正方形,n既等于行数也等于列数。行数是随着数组下标自动增加的,i等于列数,n是总列数
arr[currentRow] = i;//遍历每个列数,把值传递给数组然后判断是否符合条件
if (judge(currentRow)) {//判断是否符合条件
check(n, currentRow + 1);//该行数符合条件,进行下一行的皇后判断
}
}
}
}
public boolean judge(int currentRow) {//判断方法
for (int i = 0; i < currentRow; i++) {//对该行的皇后,和前几行的皇后进行判断,是否在同一条直线(只有列,因为行是天然不相同的)或者斜线上
if (arr[i] == arr[currentRow] ||//判断是否在同一列,数组的值就代表每一个皇后的列,i就是每个皇后的行值,把当前行之前的所有行的皇后遍历并比较
Math.abs(currentRow - i) == Math.abs(arr[currentRow] - arr[i])) {
//判断是否在同一斜线。斜线有两条,斜率互为相反值,用绝对值可缩减为一次判断
//根据x1-x2 是否等于y1-y2判断
return false;//如果相同,说明直线上或斜线上有皇后,该位置不能放皇后
}
}
return true;//for完整循环完毕出来之后,该位置可放皇后
}
//在main方法里new本类对象的实例,然后调用queen()方法即可
}
作用域和变量
- 属性和局部变量可以重名,访问时遵循就近原则
- 同一个作用域中,比如在同一个成员方法中,两个局部变量不能重名
- 属性生命周期较长,伴随着对象的创建而创建,销毁而销毁
- 局部变量生命周期较短,伴随着它的代码块的执行而创建,伴随着代码块的结束而销毁
修饰符
- 全局变量可以加修饰符
- 局部变量不能加修饰符
this关键字
细节:
- this关键字可以用来访问本类的属性、方法、构造器
- this用于区分当前类的属性和局部变量
- 访问成员方法的语法:this.方法名(参数列表)
- 访问构造器的语法:this(参数列表)注意只能在构造器中调用另一个构造器。
- this不能在类定义的外部使用,只能在类定义的方法中使用
匿名对象
匿名只能用一次
因为没有名字,来引用它,所以只能在创建的时候知道它的位置并使用。用完之后就没办法调用它了。
new Test().count();

浙公网安备 33010602011771号