Java遞歸尋路實現,你真的理解瞭嗎
引
看懂這張圖,方法調用方法,棧開新棧,遞歸尾結束要回到main棧,必須一級一級返回,每一次返回都是調用整個方法,調用完成棧被釋放,直至回到棧底main遞歸結束並能夠自己畫出來,理解遞歸的運行機制,這是我手畫的,不好看,你的呢,還不動起來
到這,如果上面的你都理解瞭,那麼我相信你可以用遞歸寫出 計算 n 的階乘的程序瞭,什麼,寫不出,沒有關系,我來補上,一定要理解在棧裡運行機制
使用遞歸計算階乘
public class Factorial { public static void main(String[] args) { Factorial jie = new Factorial (); System.out.println(jie.f(3)); } public int f(int n){ if(n == 1){ return 1; }else { return n*f(n-1); } } }
接下來就可以玩起來瞭,一個有趣的迷宮問題,假設有如下二維數組表示地圖,數字1表示圍墻,數字0表示可以走,現在有隻小老鼠被困在下標為[1][1]的位置,出口在下標為[6][5]的位置,思考:使用遞歸如何讓小老鼠尋路逃生呢?
思考過後,腦袋是不是蒙蒙的
想要玩起來
地圖創建
思路
1. 先創建迷宮,用二維數組表示 int[][] map = new int[8][7];
2. 規定 map:0 表示可以走,1表示墻不能走
1,打印二維數組
public class miGong { public static void main(String[] args) { int[][] map = new int[8][7]; 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(); } } }
2,規定墻和可以走的,隻需要通過遍歷指定行和列,再把兩個特別的單獨強調,完成
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;
實現效果:
核心
這時就完成瞭地圖,思考如何使用遞歸尋路呢
開始吧,寫一個方法,通過遞歸來實現尋路,我直接放代碼瞭
- 首先,創建一個類,寫findWay方法,返回值是boolean,三個參數,分別是地圖,二維坐標x,y用來確定位置
- 接著,我們判斷如果map[6][5] == 2,就認為小老鼠找到出口瞭,這點很重要,它是遞歸回調條件
- 如果map[6][5] == 2條件為假,說明小老鼠沒有找到出口,調用方法時初始化開始坐標,接著map[i][j] = 2;假設可以走通就把坐標的值修改為2,表示老鼠走的痕跡
- 接下來,奇妙的事情發生瞭,遞歸就在這裡開始瞭,我們調用自己findWay傳入參數,我們先確定下來小老鼠的行走軌跡,假設是下-右-上-左,我們通過修改數組下標來表示小老鼠的移動,假設上下左右都沒能走通,就把坐標值修改為3,表示小老鼠被困死瞭,返回false,失敗,🆗,代碼已經完成
- 小夥伴:什麼???完成瞭???
class way{ //使用遞歸回溯的思想來解決 public boolean findWay(int[][] map,int i,int j){ if(map[6][5] == 2){ return true; }else{ if(map[i][j] == 0){ //假定可以走通 map[i][j] = 2; //下-右-上-左 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 { return false; } } } }
主函數調用,查看結果:
way f = new way(); f.findWay(map,1,1); System.out.println("=====找路====="); 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(); }
運行代碼查看結果:
看到成功尋路逃生~~~,是不是還很疑惑
一定要理解透,你也可以設置死路,隻要上面的理解瞭,達到能在腦子裡快速回放遞歸的過程,棧開棧,棧銷毀,等等,你就可以隨便玩瞭,之前是不是一直不理解為什麼說遞歸占用空間,謹慎使用,這下就明明白白瞭,好瞭,多理解理解,這就是所有內容,感受到遞歸的魅力瞭嗎?哈哈 是不是很好玩,體會這種思想,感謝觀看
完整代碼
public class miGong { public static void main(String[] args) { //思路 //1.先創建迷宮,用二維數組表示 int[][] map = new int[8][7]; //2.規定 map:0 表示可以走,1表示墻不能走 int[][] map = new int[8][7]; 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; //打印 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(); } way f = new way(); f.findWay(map,1,1); System.out.println("=====找路====="); 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 way{ //使用遞歸回溯的思想來解決 public boolean findWay(int[][] map,int i,int j){ if(map[6][5] == 2){ return true; }else{ if(map[i][j] == 0){ //假定可以走通 map[i][j] = 2; //下-右-上-左 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 { return false; } } } }
總結
本篇文章就到這裡瞭,希望能給你帶來幫助,也希望您能夠多多關註WalkonNet的更多內容!