目录

简要解析

回溯法

一解(预见算法、栈实现回溯)

多解(预见算法、栈实现回溯)

全解(回溯,暴力递归)

运行结果图

其他代码

变量

构造函数

判断该点的direction方向是否可走

预见算法

打印路径

打印棋盘

多解的全部代码

end


简要解析

回溯法

回溯法都叫backTrack

一解(预见算法、栈实现回溯)

   /*** x[] 走过的方向* dirList 第i层的可选方向* p 点坐标* i 层数* chessboard[][] 记录走法* 需要入栈的变量 : dirList p* 技术难题: dirList的入栈出栈 与使用* 时间复杂度O(n^2*n)=O(n^3) <--> 空间复杂度O(n*n)*/public void backTrack(Point p) //非递归方式的 栈 深度优先 回溯{                               //栈如何转化多个分叉的递归int[]x=new int[n*n+1];pathlen=1;int i=1;chessboard[p.x][p.y]=1;LinkedStack<Point> stack=new LinkedStack<>();stack.push(p);SeqList<Integer> dirList;while (p!=null || !stack.isEmpty())  //当前p在i+1层{if(i==n*n){count++;System.out.println("第"+count+"个解");stack.pop();printMat();chessboard[p.x][p.y]=0;i--;break;}dirList=select(p);//对于预见算法select 当到达第24层时,p的下一节点只有一个,而且宽度为0if(x[i]<dirList.size() ) //找到可行解{p=restrict(p,dirList.get(x[i]));x[i]++;i++;pathlen=i;chessboard[p.x][p.y]=i;stack.push(p);}else  //没有下一个可行点,回溯{chessboard[stack.peek().x][stack.peek().y] = 0;stack.pop();p=stack.peek();x[i]=0;i--;}}}

多解(预见算法、栈实现回溯)

一个解就是找到一个解就退出循环,结束程序

    /*** x[] 走过的方向* dirList 第i层的可选方向* p 点坐标* i 层数* chessboard[][] 记录走法* 需要入栈的变量 : dirList p* 技术难题: dirList的入栈出栈 与使用* 时间复杂度O(n^2*n)=O(n^3) <--> 空间复杂度O(n*n)*/public void backTrack(Point p) //非递归方式的 栈 深度优先 回溯{                               //栈如何转化多个分叉的递归int[]x=new int[n*n+1];pathlen=1;int i=1;chessboard[p.x][p.y]=1;LinkedStack<Point> stack=new LinkedStack<>();stack.push(p);SeqList<Integer> dirList;while (p!=null || !stack.isEmpty())  //当前p在i+1层{if(i==n*n){count++;System.out.println("第"+count+"个解");stack.pop();printMat();chessboard[p.x][p.y]=0;i--;
//                break;}dirList=select(p);//对于预见算法select 当到达第24层时,p的下一节点只有一个,而且宽度为0if(x[i]<dirList.size() ) //找到可行解{p=restrict(p,dirList.get(x[i]));x[i]++;i++;pathlen=i;chessboard[p.x][p.y]=i;stack.push(p);}else  //没有下一个可行点,回溯{chessboard[stack.peek().x][stack.peek().y] = 0;stack.pop();p=stack.peek();x[i]=0;i--;}}}

全解(回溯,暴力递归)

protected void backTrack(int i,Point p)
{if(i<=this.n*this.n){this.pathlen=i;chessboard[p.x][p.y]=i;if(i==this.n*this.n)return;
​for(int j=1;j<=8;j++){Point next=restrict(p,j); //八个方向 每个方向都递归if(next!=null)  //有下一个位置,则前进到下一个位置{backTrack(i+1,next);
​if(i+1==pathlen)  //下一步走完 就没有后路了,所以路径终止在p0到p(i+1){if(show){path++;System.out.print("第"+path+"条路径");
​}if(i+1==this.n*this.n){count++;System.out.print("第"+count+"个解");System.out.print("时刻:"+(System.currentTimeMillis()-startTime)/1000+"s");System.out.println();list.add(new ChessBoard(chessboard));//                            this.print();  //输出一条路径/一个解printMat();}
​}chessboard[next.x][next.y]=0;  //next走完后,退回到前一个递归函数的状态,走下一个next方向}}}
}

运行结果图

其他代码

变量

protected final int n;  //棋盘规格为 n*n
protected int chessboard[][];
protected boolean show;
protected int pathlen,path,count;

构造函数

public Knight_Stack(int n, int x, int y, boolean show)
{if(n>=3 && n<=50)this.n = n;elsethrow new IllegalArgumentException("n="+n);chessboard=new int[n][n]; //初始值为0System.out.println("n="+n+",point="+new Point(x,y));this.show=show;pathlen=0;path=0;count=0;
//  backTrack(1,new Point(x,y)) ; //递归backTrack(new Point(x,y));  //栈System.out.println("共有"+count+"个解");
}

判断该点的direction方向是否可走

    protected Point restrict(Point point,int direction){int x=point.x,y=point.y;switch(direction){case 1:x-=2 ;y++; break;case 2:x--;  y+=2;break;case 3:x++;  y+=2;break;case 4:x+=2; y+=1;break;case 5:x+=2; y--; break;case 6:x+=1; y-=2;break;case 7:x-=1; y-=2;break;case 8:x-=2; y-=1;break;}if(x>=0 && x<this.n && y>=0 && y<this.n && this.chessboard[x][y]==0)return new Point(x,y);      //0表示还没有经过,没有走过return null;}

预见算法

protected SeqList<Integer> select(Point p)  //返回大小为n的线性表,方向按照 路的“宽度”从小到大存放{                                           //求得下一步8个方向位置的路的“宽度”,并将元素从大到小拍放在线性表,,不如排序线性表。。if(show){System.out.println("当前点为:" + p);//           print();//打印当前路径printMat();}
//        计算宽度,以当前点为下一节点,计算自己可走的路数Point next;int minRoad=8;SeqList<Integer> list=new SeqList<>();for(int k=1;k<=8;k++)   //选择宽度最小的方向,并且将宽度最小的方向{int avl = 0;next=restrict(p,k);if(next!=null && chessboard[next.x][next.y]==0)  //下一步,不仅要有,还得时未走过的{for (int i = 1; i <= 8; i++)if (restrict(next, i) != null)avl++;if(avl<minRoad){minRoad=avl;list.clear();}if(avl==minRoad)list.insert(k);}}return list;}

打印路径

    protected void print()  //输出路径  从点(x,y)开始{String str="[";for(int k=1;k<=n*n;k++)for(int i=0;i<n;i++)for(int j=0;j<n;j++){if(chessboard[i][j]==k)  //得到顺序路径上的一点p(i,j)str+=new Point(i,j)+",";}if(str.length()>1)str=str.substring(0,str.length()-1);System.out.println(str+"]");}

打印棋盘

private void printMat(){for (int i=0;i<n;i++){for (int j = 0; j < n; j++)System.out.printf("%5d",chessboard[i][j]);System.out.println();}}

多解的全部代码

package chapter_10_courseDesign;import chapter_1_1_SeqLIst.SeqList;
import chapter_3_1_Stack_Queue.LinkedStack;public class Knight //二维数组chessBoard存储n*n棋盘的一个解,使用预见算法 回溯算法
{protected final int n;  //棋盘规格为 n*nprotected int chessboard[][];protected boolean show;protected int pathlen,path,count;public Knight(int n, int x, int y, boolean show){if(n>=3 && n<=12)this.n = n;elsethrow new IllegalArgumentException("n="+n);chessboard=new int[n][n]; //初始值为0System.out.println("n="+n+",point="+new Point(x,y));this.show=show;pathlen=1;path=0;count=0;
//        backTrack(1,new Point(x,y));backTrack(new Point(x,y));System.out.println("共有"+count+"个解");}/*** x[] 走过的方向* dirList 第i层的可选方向* p 点坐标* i 层数* chessboard[][] 记录走法* 需要入栈的变量 : dirList p* 技术难题: dirList的入栈出栈 与使用* 时间复杂度O(n^2*n)=O(n^3) <--> 空间复杂度O(n*n)*/public void backTrack(Point p) //非递归方式的 栈 深度优先 回溯{                               //栈如何转化多个分叉的递归int[]x=new int[n*n+1];pathlen=1;int i=1;chessboard[p.x][p.y]=1;LinkedStack<Point> stack=new LinkedStack<>();stack.push(p);SeqList<Integer> dirList;while (p!=null || !stack.isEmpty())  //当前p在i+1层{if(i==n*n){count++;System.out.println("第"+count+"个解");stack.pop();printMat();chessboard[p.x][p.y]=0;i--;
//                    break;}dirList=select(p);//对于预见算法select 当到达第24层时,p的下一节点只有一个,而且宽度为0if(x[i]<dirList.size() ) //找到可行解{p=restrict(p,dirList.get(x[i]));x[i]++;i++;pathlen=i;chessboard[p.x][p.y]=i;stack.push(p);
//                dirStack.push(dirList);}else  //没有下一个可行点,回溯{chessboard[stack.peek().x][stack.peek().y] = 0;stack.pop();
//                dirStack.pop();p=stack.peek();x[i]=0;i--;}}}protected void backTrack(int i,Point p){if(i<=this.n*this.n){this.pathlen=i;chessboard[p.x][p.y]=i;if(i==this.n*this.n)     //到达叶子节点,直接返回,回溯return;SeqList<Integer> direList=this.select(p);   //预见算法给出的方向选择for(int j=0;j<direList.size();j++){Point next=restrict(p,direList.get(j));if(next!=null)  //有下一个位置,则前进到下一个位置{backTrack(i+1,next);if(i+1==pathlen)  //下一步走完 就没有后路了,所以路径终止在p0到p(i+1){if(show){path++;System.out.print("第"+path+"条路径");}if(i+1==this.n*this.n){count++;System.out.print("第"+count+"个解");}System.out.println();printMat();}chessboard[next.x][next.y]=0;  //next点走完后,退回到前一个递归函数的状态,走下一个next方向}}}}protected void print()  //输出路径  从点(x,y)开始{String str="[";for(int k=1;k<=n*n;k++)for(int i=0;i<n;i++)for(int j=0;j<n;j++){if(chessboard[i][j]==k)  //得到顺序路径上的一点p(i,j)str+=new Point(i,j)+",";}if(str.length()>1)str=str.substring(0,str.length()-1);System.out.println(str+"]");}private void printMat(){for (int i=0;i<n;i++){for (int j = 0; j < n; j++)System.out.printf("%3d",chessboard[i][j]);System.out.println();}}protected SeqList<Integer> select(Point p)  //返回大小为n的线性表,方向按照 路的“宽度”从小到大存放{                                           //求得下一步8个方向位置的路的“宽度”,并将元素从大到小拍放在线性表,,不如排序线性表。。if(show){System.out.println("当前点为:" + p);print();//打印当前路径
//            printMat();}
//        计算宽度,以当前点为下一节点,计算自己可走的路数Point next;int minRoad=8;SeqList<Integer> list=new SeqList<>();for(int k=1;k<=8;k++)   //选择宽度最小的方向,并且将宽度最小的方向{int avl = 0;next=restrict(p,k);if(next!=null && chessboard[next.x][next.y]==0)  //下一步,不仅要有,还得时未走过的{for (int i = 1; i <= 8; i++)if (restrict(next, i) != null)avl++;if(avl<minRoad){minRoad=avl;list.clear();}if(avl==minRoad)list.insert(k);}}return list;}protected Point restrict(Point point,int direction){int x=point.x,y=point.y;switch(direction){case 1:x-=2 ;y++; break;case 2:x--;  y+=2;break;case 3:x++;  y+=2;break;case 4:x+=2; y+=1;break;case 5:x+=2; y--; break;case 6:x+=1; y-=2;break;case 7:x-=1; y-=2;break;case 8:x-=2; y-=1;break;}if(x>=0 && x<this.n && y>=0 && y<this.n && this.chessboard[x][y]==0)return new Point(x,y);      //0表示还没有经过,没有走过return null;}public static void main(String[] args){long start=System.currentTimeMillis();Knight knight=new Knight(5,0,0,true);System.out.println("用时"+(System.currentTimeMillis()-start)+"ms");}
}

end

骑士游历(Java课设)相关推荐

  1. 【源码+教程】Java课设项目_12款最热最新Java游戏项目_Java游戏开发_Java小游戏_飞翔的小鸟_王者荣耀_超级玛丽_推箱子_黄金矿工_贪吃蛇

    马上就要期末了,同学们课设做的如何了呢?本篇为大家带来了12款热门Java小游戏项目的源码和教程,助力大家顺利迎接暑假![源码+教程]Java课设项目_12款最热最新Java游戏项目_Java游戏开发 ...

  2. java 课设 商品库存管理系统

    比较辛苦的java课设!写了蛮久的,战斗了好多个通宵. 下载https://download.csdn.net/download/qq_37871063/10297290 入门:JAVAFX+MVC+ ...

  3. 华南农业大学课设——数据结构课设、Java课设、操作系统课设

    文章目录 缘起 大二上-数据结构课设(高校教学管理系统)-C++.Qt 视频演示 感想 大二下-Java课设(流程图绘制程序)-JavaFX 视频演示 感想 大三上-操作系统课设(模拟磁盘文件系统实现 ...

  4. 学生信息管理系统(成绩统计)Java课设

    下载地址:学生信息管理系统(成绩统计)Java课设-Web服务器文档类资源-CSDN下载 ├── StudentInfo │   ├── bin │   │   ├── com │   │   │   ...

  5. JAVA课设单人版五子棋小游戏

    内容介绍:该程序为Java课设的单人版五子棋小游戏,通过eclipse编辑,实现了动作事件的监听与处理,以及JavaSwing的界面编程.  编辑排行榜,包含局数,结果,步数,以及"关于我们 ...

  6. Java课设——ArxivHelper

    项目地址https://github.com/PKUCSS/arxiv-helper How to run运行方式:java -jar arxiv-helper.jar Tips:We use pyi ...

  7. 100套java课设源码参考/毕设源码代码参考

    引言:本人是一个Java 开发者,喜欢分享Java课设源码和代码,用于课程设计或者作业学习参考噢,开发一些有技术含量的Java web源码,主要的技术有JSP+Servlet,SSM/SpringBo ...

  8. JAVA课设:电子英汉词典(附源码+调试)

    JAVA课设:电子英汉词典 电子英汉词典功能概述 整体要求:用图形用户界面实现,能够编辑词典库中的信息,能够实现英译汉,汉译英.(要考虑一词多义) 具体实现:1.用图形用户界面实现:2.能够实现英译汉 ...

  9. 【Java课设】--ATM取款机(Gui界面)

    [Java课设]–ATM取款机(Gui界面)

最新文章

  1. OO第三单元作业总结
  2. Android之linux基础教学之七 中断下半部之软中断
  3. P1417 烹调方案 (0/1背包+贪心)
  4. LeetCode 872叶子相似的树-简单
  5. [Oracle]如何查看一个数据文件是否是自动扩展
  6. 【文智背后的奥秘】系列篇——分布式爬虫之WebKit
  7. 开源demo| 视频应用类开源 Demo 大盘点
  8. Matlab数据库工具箱的简单使用
  9. python字体和图片合成
  10. [BUG 记录] Ubuntu下Tesla M40与其他N卡共存安装
  11. 纯css写滚动的弹幕特效
  12. “华为“和“荣耀”区别日益明显,荣耀传递潮流价值观
  13. 如何创建XS Job来完成定时任务
  14. Booting ARM Linux
  15. Python机器学习、深度学习库总结
  16. 有五万块钱,在农村养牛怎么样?能养多少头牛?
  17. Weblogic常见报错以及解决方法[转载]
  18. 有关数据包拓展基础知识
  19. 早期的行人再识别与深度行人再识别研究——行人再识别技术综述阅读笔记
  20. 自定义 SAP 采购订单屏幕

热门文章

  1. 上班族的年末,太难了!
  2. 查看nginx版本号的几种方法
  3. linux启动logo修改 bootlogo
  4. 年龄是个硬门槛!42岁,腾讯13级,985硕士,找工作三个月,居然没有一家公司接收!...
  5. 腾讯首页js图片切换效果
  6. 聊聊SpringAOP和自定义注解的通用性
  7. 00911无效字符oracle,ORA-00911: 无效字符 解决
  8. Axialis IconWorkshop破解版不能用了?看这个替换品
  9. 前端甘特图组件开发(一)
  10. ISAKMP报文解密