5.1 从计算机底层对递归理解
递归理解:
在计算机内部调用递归会将每一次调用递归方法放入栈中,直到满足退出条件才从栈顶依次销毁并回归
5.2对于递归注意的是
-
对于递归首先需要判断是不是重复性问题,是重复性问题就可以运用递归
-
一般不用递归,可能会导致栈溢出
-
运用递归需要明确递归退出条件、
-
明确递归方法是要完成什么任务
-
抽象理解 理解递归不要从全局理解,只想某一次调用它需要做什么 比如阶乘递归: 我第三次调用递归时我只需要考虑我现在需要的是第四次递归的结果帮助我完成 ,没有它我完成不了我的任务 而不去想整体是在干嘛,
5.3递归一定要明确我每一个方法到底是为了达到什么目的
5.4 八皇后算法
八皇后问题通过递归+回溯需要明确几个点:
首先以一维数组表示棋盘,数组下标表示皇后,数组值表示皇后的位置
创建 判断皇后位置是否能放置 的方法时,一定要明确此方法只是为了判断当前皇后能否放置在某处,他只是用来做判断的,不会改变皇后的位置
创建 皇后递归方法 时 ,要明确递归退出条件是到第九个皇后时就退出,进行递归时每次调用递归都会进行8次循环,确定出皇后的位置;
回溯时是从最后依次回溯,所以会进行很多次重复的操作
代码:
<span style="background-color:#333333"><span style="color:#c88fd0">public</span> <span style="color:#c88fd0">class</span> <span style="color:#8d8df0">eightQueens</span> { <span style="color:#da924a">// 用一维数组表示二维棋盘,数组下标+1表示行数 数组值表示皇后的位置</span> <span style="color:#c88fd0">private</span> <span style="color:#1cc685">int</span>[] <span style="color:#b8bfc6">map</span> <span style="color:#b8bfc6">=</span> <span style="color:#c88fd0">new</span> <span style="color:#1cc685">int</span>[<span style="color:#64ab8f">8</span>];<span style="color:#da924a">//定义棋盘</span> <span style="color:#c88fd0">private</span> <span style="color:#c88fd0">static</span> <span style="color:#1cc685">int</span> <span style="color:#b8bfc6">count</span> <span style="color:#b8bfc6">=</span> <span style="color:#64ab8f">0</span>; <span style="color:#c88fd0">public</span> <span style="color:#c88fd0">static</span> <span style="color:#1cc685">void</span> <span style="color:#b8bfc6">main</span>(<span style="color:#1cc685">String</span>[] <span style="color:#b8bfc6">args</span>) { <span style="color:#b8bfc6">eightQueens</span> <span style="color:#b8bfc6">eightQueens</span> <span style="color:#b8bfc6">=</span> <span style="color:#c88fd0">new</span> <span style="color:#b8bfc6">eightQueens</span>(); <span style="color:#b8bfc6">eightQueens</span>.<span style="color:#b8bfc6">getQueenWays</span>(<span style="color:#64ab8f">0</span>); <span style="color:#b8bfc6">System</span>.<span style="color:#b8bfc6">out</span>.<span style="color:#b8bfc6">printf</span>(<span style="color:#d26b6b">"一共有%d种解法"</span>, <span style="color:#b8bfc6">count</span>); } <span style="color:#da924a">/**</span> <span style="color:#da924a">* 具体皇后递归实现</span> <span style="color:#da924a">*</span> <span style="color:#da924a">* @param n 传入第几个皇后</span> <span style="color:#da924a">*/</span> <span style="color:#c88fd0">public</span> <span style="color:#1cc685">void</span> <span style="color:#b8bfc6">getQueenWays</span>(<span style="color:#1cc685">int</span> <span style="color:#b8bfc6">n</span>) { <span style="color:#da924a">//首先给出退出递归条件</span> <span style="color:#c88fd0">if</span> (<span style="color:#b8bfc6">n</span> <span style="color:#b8bfc6">==</span> <span style="color:#64ab8f">8</span>) { <span style="color:#c88fd0">for</span> (<span style="color:#1cc685">int</span> <span style="color:#b8bfc6">i</span> <span style="color:#b8bfc6">=</span> <span style="color:#64ab8f">0</span>; <span style="color:#b8bfc6">i</span> <span style="color:#b8bfc6"><</span> <span style="color:#b8bfc6">map</span>.<span style="color:#b8bfc6">length</span>; <span style="color:#b8bfc6">i</span><span style="color:#b8bfc6">++</span>) { <span style="color:#b8bfc6">System</span>.<span style="color:#b8bfc6">out</span>.<span style="color:#b8bfc6">print</span>(<span style="color:#b8bfc6">map</span>[<span style="color:#b8bfc6">i</span>] <span style="color:#b8bfc6">+</span> <span style="color:#d26b6b">" "</span>); } <span style="color:#b8bfc6">System</span>.<span style="color:#b8bfc6">out</span>.<span style="color:#b8bfc6">println</span>(); <span style="color:#b8bfc6">count</span><span style="color:#b8bfc6">++</span>; <span style="color:#c88fd0">return</span>; } <span style="color:#da924a">// 循环放置某一个皇后位置并进行判断</span> <span style="color:#c88fd0">for</span> (<span style="color:#1cc685">int</span> <span style="color:#b8bfc6">i</span> <span style="color:#b8bfc6">=</span> <span style="color:#64ab8f">0</span>; <span style="color:#b8bfc6">i</span> <span style="color:#b8bfc6"><</span> <span style="color:#b8bfc6">map</span>.<span style="color:#b8bfc6">length</span>; <span style="color:#b8bfc6">i</span><span style="color:#b8bfc6">++</span>) { <span style="color:#b8bfc6">map</span>[<span style="color:#b8bfc6">n</span>] <span style="color:#b8bfc6">=</span> <span style="color:#b8bfc6">i</span>;<span style="color:#da924a">//将皇后放置在当前位置</span> <span style="color:#c88fd0">if</span> (<span style="color:#b8bfc6">check</span>(<span style="color:#b8bfc6">n</span>)) {<span style="color:#da924a">//判断当前位置能否放置</span> <span style="color:#da924a">// 这里每一次递归都会进行最多8次循环</span> <span style="color:#b8bfc6">getQueenWays</span>(<span style="color:#b8bfc6">n</span> <span style="color:#b8bfc6">+</span> <span style="color:#64ab8f">1</span>);<span style="color:#da924a">//可以放置就递归传入下一个皇后</span> } } } <span style="color:#da924a">/**</span> <span style="color:#da924a">* 判断当前位置能否放置皇后</span> <span style="color:#da924a">* 只做判断,并不能改变传入皇后的位置</span> <span style="color:#da924a">*</span> <span style="color:#da924a">* @param n 传入的某一列的位置(传入皇后)</span> <span style="color:#da924a">* @return</span> <span style="color:#da924a">*/</span> <span style="color:#c88fd0">public</span> <span style="color:#1cc685">boolean</span> <span style="color:#b8bfc6">check</span>(<span style="color:#1cc685">int</span> <span style="color:#b8bfc6">n</span>) { <span style="color:#da924a">/*</span> <span style="color:#da924a">八皇后问题条件:不能在同一行</span> <span style="color:#da924a">不能再同一列</span> <span style="color:#da924a">不能再统一斜线上</span> <span style="color:#da924a">*/</span> <span style="color:#da924a">// 将当前皇后同棋盘上所有皇后进行对比</span> <span style="color:#da924a">// 注意这里的n 是判断当前皇后与他之前的进行比较</span> <span style="color:#c88fd0">for</span> (<span style="color:#1cc685">int</span> <span style="color:#b8bfc6">i</span> <span style="color:#b8bfc6">=</span> <span style="color:#64ab8f">0</span>; <span style="color:#b8bfc6">i</span> <span style="color:#b8bfc6"><</span> <span style="color:#b8bfc6">n</span>; <span style="color:#b8bfc6">i</span><span style="color:#b8bfc6">++</span>) { <span style="color:#da924a">//map[n]==map[i] 表示判断当前皇后和其他皇后在同一列</span> <span style="color:#da924a">//Math.abs(n-i) == Math.abs(map[n] - map[i]) 表示判断当前皇后和其他皇后是否在同一斜线上</span> <span style="color:#da924a">// 因为i一直在++,所以不用考虑在同一行的情况</span> <span style="color:#da924a">// 这里值对皇后做判断,下标问题只要到时候再点入函数时传入真确就行</span> <span style="color:#c88fd0">if</span> (<span style="color:#b8bfc6">map</span>[<span style="color:#b8bfc6">n</span>] <span style="color:#b8bfc6">==</span> <span style="color:#b8bfc6">map</span>[<span style="color:#b8bfc6">i</span>] <span style="color:#b8bfc6">||</span> <span style="color:#b8bfc6">Math</span>.<span style="color:#b8bfc6">abs</span>(<span style="color:#b8bfc6">n</span> <span style="color:#b8bfc6">-</span> <span style="color:#b8bfc6">i</span>) <span style="color:#b8bfc6">==</span> <span style="color:#b8bfc6">Math</span>.<span style="color:#b8bfc6">abs</span>(<span style="color:#b8bfc6">map</span>[<span style="color:#b8bfc6">n</span>] <span style="color:#b8bfc6">-</span> <span style="color:#b8bfc6">map</span>[<span style="color:#b8bfc6">i</span>])) {<span style="color:#da924a">//表示不能放置</span> <span style="color:#c88fd0">return</span> <span style="color:#84b6cb">false</span>; } } <span style="color:#c88fd0">return</span> <span style="color:#84b6cb">true</span>; } } </span>