這學期給學生講《Web程序設計》,用JavaScript寫了一個八皇后問題網頁圖形版本,採用了遞歸回溯算法,下面是網頁截圖: javascript
算法並不複雜,經過DOM控制HTML標籤來顯示圖形,棋盤背景採用了表格,固然也能夠採用JavaScript來生成,但並不會使網頁代碼精簡不少。css
之因此沒有采用動態演示求解過程,是由於JavaScript沒法實現相似線程的Sleep休眠功能來延時,更沒法實現信號量、旗標等複雜的多線程功能,而JavaScript提供的setTimeout()和setInterval()方法實際上都是在瀏覽器中新開一個線程,並不會使腳本執行暫停,惟一的方法是爲每一步驟單獨編寫函數,但那樣作會使得程序異常晦澀難懂。固然,可能有人試圖經過死循環來定時,但會致使程序無響應,並且也沒法更新頁面內容,顯然這樣作是一個很是糟糕的辦法。html
這是全部代碼,能夠直接保存成網頁文件本地運行: java
- <html xmlns="http://www.w3.org/1999/xhtml">
- <head>
- <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
- <title>Eight Queens Puzzle(Recursive algorithm) - 八皇后問題(遞歸算法)</title>
- <style type="text/css">
- body {
- background-color: #ffffc0;
- }
- p {
- text-align: center;
- }
- table {
- border-width: 8px;
- border-color: #604040;
- border-style: solid;
- background-color: #ffffff;
- }
- td {
- text-align: center;
- vertical-align: middle;
- width: 70px;
- height: 70px;
- }
- td.b {
- background-color: #000000;
- }
- </style>
- <script type="text/javascript">
- var Q = new Array(8); //八皇后所在的列位置
- // 判斷第n個皇后與前面的n-1個皇后是否衝突
- function Clash(n) {
- var flag = false; //衝突標誌
- var i = 0; //從第0行逐行判斷
- while ((i < n) && !flag) {
- flag = (Q[n] == Q[i]) || (Math.abs(Q[n] - Q[i]) == (n - i)); //在同一列或相同的對角線即爲衝突
- i++;
- }
- return flag;
- }
- //搜索第n個皇后的位置
- function QSeek(n) {
- //判斷是否已經回溯到了第一個皇后以前,即已經找到了全部解
- if (n >= 0) {
- Q[n]++; //將該位置的皇后右移一個位置
- if (Q[n] < 8) //當前行的皇后右移未超出範圍
- {
- if (Clash(n)) //衝突則繼續搜索當前行的皇后位置
- return QSeek(n)
- else //不衝突則當前行搜索完成
- return true;
- }
- else //當前行沒法安放,遞歸回溯
- {
- Q[n] = -1; //刪除當前行的皇后
- if (QSeek(n - 1)) //遞歸回溯
- return QSeek(n) //在前一行搜索成功時,再搜索當前行
- else
- return false; //無解
- }
- }
- else
- return false; //無解
- }
- var pic = "f0"; //默認的皇后圖片字符串
- //刷新皇后圖片
- function showQueens() {
- //清除原有圖像,即清除全部TD標記中的內容
- var tds = document.getElementsByTagName("TD");
- for (var i = 0; i < tds.length; i++)
- tds[i].innerHTML = "";
- //繪製新圖像
- for (var i = 0; i < 8; i++) {
- eval("r" + i + "c" + Q[i] + ".innerHTML = \"<img src=\\\"" + pic + ".png\\\" />\";");
- }
- }
- var count = 1; //記錄解的個數
- function Queens() {
- seekbtn.disabled = true; //禁用按鈕
- seekpic.disabled = true; //禁用下拉列表
- if (count == 1) { //求第一組解時需搜索前7個皇后的位置
- for (var i = 0; i < 7; i++)
- QSeek(i);
- }
- if (QSeek(7)) {
- showQueens();
- seekbtn.value = "已經搜索到第" + count + "組解,準備搜索第" + ++count + "組解...";
- seekpic.disabled = false; //恢復下拉列表
- seekbtn.disabled = false; //恢復按鈕
- seekbtn.focus(); //設置焦點到按鈕
- }
- else
- seekbtn.value = "所有解已經搜索完成,共" + (count - 1) + "組!";
- }
- </script>
- </head>
- <body>
- <p>
- Eight Queens Puzzle (Recursive algorithm) - 八皇后問題(遞歸算法)<br />
- Mengliao Software Studio(Baiyu) - 夢遼軟件工做室(白宇)<br />
- Copyright 2011, All right reserved. - 版權全部(C) 2011<br />
- 2011.04.04</p>
- <center>
- <table cellpadding="0" cellspacing="0">
- <tr>
- <td id="r0c0"></td>
- <td class="b" id="r0c1"></td>
- <td id="r0c2"></td>
- <td class="b" id="r0c3"></td>
- <td id="r0c4"></td>
- <td class="b" id="r0c5"></td>
- <td id="r0c6"></td>
- <td class="b" id="r0c7"></td>
- </tr>
- <tr>
- <td class="b" id="r1c0"></td>
- <td id="r1c1"></td>
- <td class="b" id="r1c2"></td>
- <td id="r1c3"></td>
- <td class="b" id="r1c4"></td>
- <td id="r1c5"></td>
- <td class="b" id="r1c6"></td>
- <td id="r1c7"></td>
- </tr>
- <tr>
- <td id="r2c0"></td>
- <td class="b" id="r2c1"></td>
- <td id="r2c2"></td>
- <td class="b" id="r2c3"></td>
- <td id="r2c4"></td>
- <td class="b" id="r2c5"></td>
- <td id="r2c6"></td>
- <td class="b" id="r2c7"></td>
- </tr>
- <tr>
- <td class="b" id="r3c0"></td>
- <td id="r3c1"></td>
- <td class="b" id="r3c2"></td>
- <td id="r3c3"></td>
- <td class="b" id="r3c4"></td>
- <td id="r3c5"></td>
- <td class="b" id="r3c6"></td>
- <td id="r3c7"></td>
- </tr>
- <tr>
- <td id="r4c0"></td>
- <td class="b" id="r4c1"></td>
- <td id="r4c2"></td>
- <td class="b" id="r4c3"></td>
- <td id="r4c4"></td>
- <td class="b" id="r4c5"></td>
- <td id="r4c6"></td>
- <td class="b" id="r4c7"></td>
- </tr>
- <tr>
- <td class="b" id="r5c0"></td>
- <td id="r5c1"></td>
- <td class="b" id="r5c2"></td>
- <td id="r5c3"></td>
- <td class="b" id="r5c4"></td>
- <td id="r5c5"></td>
- <td class="b" id="r5c6"></td>
- <td id="r5c7"></td>
- </tr>
- <tr>
- <td id="r6c0"></td>
- <td class="b" id="r6c1"></td>
- <td id="r6c2"></td>
- <td class="b" id="r6c3"></td>
- <td id="r6c4"></td>
- <td class="b" id="r6c5"></td>
- <td id="r6c6"></td>
- <td class="b" id="r6c7"></td>
- </tr>
- <tr>
- <td class="b" id="r7c0"></td>
- <td id="r7c1"></td>
- <td class="b" id="r7c2"></td>
- <td id="r7c3"></td>
- <td class="b" id="r7c4"></td>
- <td id="r7c5"></td>
- <td class="b" id="r7c6"></td>
- <td id="r7c7"></td>
- </tr>
- </table>
- <br />皇后圖片選擇:
- <select id="seekpic" disabled="disabled" onchange="JavaScript: pic=this.value; showQueens();">
- <option value="f0" selected="selected">圖片一</option>
- <option value="f1">圖片二</option>
- <option value="f2">圖片三</option>
- <option value="f3">圖片四</option>
- <option value="f4">圖片五</option>
- <option value="f5">圖片六</option>
- <option value="f6">圖片七</option>
- <option value="f7">圖片八</option>
- <option value="f8">圖片九</option>
- <option value="f9">圖片十</option>
- </select>
- <input style="width: 300px; height: 25px" type="button" id="seekbtn" value="準備搜索第1組解..." onclick="Queens()" />
- </center>
- </body>
- </html>
標準的遞歸回溯算法,在求的每一組解後將末行的皇后向後移動一個位置繼續求解,天然就是下一組解了,當全部解(共92組)求出後,將致使主函數返回false。算法