数据结构与算法——Java实现递归、迷宫回溯问题、八皇后问题

news2025/1/18 20:27:50

目录

一、递归

1.1 介绍递归

二、迷宫回溯问题

2.1 代码实现

三、八皇后问题

3.1 基本介绍

3.2 分析思路

3.3 代码实现


一、递归

1.1 介绍递归

简单的说:递归就是方法自己调用自己,每次传入不同的变量。

递归有助于编程者解决复杂的问题,同时可以让代码变得简洁。

递归可以解决什么样的问题?

  •   八皇后问题、汉诺塔、阶乘、迷宫、球和蓝子
  •   各种算法中也会使用到递归,比如快排,归并排序,二分查找,分治算法等
  •   把用栈解决的问题编程递归代码比较简洁

递归重要的规则

  •  执行一个方法时,就创建一个新的受保护的独立空间(栈空间)
  •  方法的局部变量是独立的,不会相互影响的
  •  如果方法中使用的是引用数据类型变量(比如数组,每一次递归都是用的同一个数据,修改的同一个数据),就会共享该引用数据类型的数据
  •   递归必须向退出递归的条件逼近,否则死循环
  •   当一个方法执行完毕,或者遇到return,就会返回。遵守谁调用,就将结果返回给谁,同时当方法执行完毕或者返回时,该方法也就执行完毕。

二、迷宫回溯问题

最短路径和程序员找的策略有关

2.1 代码实现


public class MiGong {
    public static void main(String[] args) {
//       创建二维数组模拟迷宫   八行七列
        int[][] map = new int[8][7];
//       数字1代表墙  第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;

//      模型输出一下
        for(int i=0 ;i<8 ; i++){
            for (int j=0; j<7;j++){
                System.out.print(map[i][j]+"   ");
            }
            System.out.println();
        }
        System.out.println("***********************递归回溯开始!!!!!!*********************");
//      递归回溯
        setWay(map,1,1);
//      输出小球走过的路
        for(int i=0 ;i<8 ; i++){
            for (int j=0; j<7;j++){
                System.out.print(map[i][j]+"   ");
            }
            System.out.println();
        }
    }

    /**
     * 递归开始处是11  结束处是65
     * 约定: map[i][j]=0时没有走过,1表示墙,2表示走过,是通路,3表示走过了这个路走不通
     *      如果能走到map[6][5]位置,既map[6][5],说明路能通
     * 确定策略:在走迷宫的时候按照 先走下面,走不通走右面,再走不通走上面,再走不通走左面 ,如果该点走不通再回溯
     *使用递归回溯给小球找路 找到为true
     * @param map 地图
     * @param i   从哪个位置开始找
     * @param j   从哪个位置开始找
     * @return    找到路返回true
     */
    public static  boolean setWay(int[][] map,int i ,int j){
           if(map[6][5] ==2 ){
//             到终点了
               return true;
           }else {
//              没有到终点,继续走
                if(map[i][j] ==0){
//                  先假定能走通,我们走走试试
                    map[i][j] =2;
                    if( setWay(map, i+1, j) ){  //向下走
                        return true;
                    }else if(setWay(map, i, j+1)){  //向右
                        return true;
                    }else if(setWay(map, i-1, j)) {  //向上
                        return true;
                    }else if(setWay(map, i, j-1)){   //向左
                        return true;
                    }else {
//                      运行到这里肯定是走不通
                        map[i][j] =3;
                        return false;
                    }

                }else {
//                  map[i][j] !=0  代表着可能是1,2,3,这三个都不满足我们走的条件
                    return false;
                }
           }
    }


}

三、八皇后问题

3.1 基本介绍

八皇后问题:是回溯算法的基本案例。在8×8格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后不能处于同一行、同一列或同一斜线,问有几种摆法

  答案是92种

3.2 分析思路

      首先说明:回溯的效率并不高,因为这就好像是每个路都走走试试行不行,这种方法就类似我们上学时学的穷举法,一个一个的试。比如我们这个8*8的棋盘就要执行一万五千多次,可见效率情况

解题说明:理论上应该创建一个二维数组来表示棋盘,但是实际上可以通过算法简化。用一个一维数组即可解决问题,arr[8]={0,4,7,5,2,6,1,3},其中数组下标对应第几列,数组下标对应的数值对应皇后放在哪个位置。比如arr[i]=var,var表示第i+1个皇后放在第i+1行的第val+1列

3.3 代码实现

public class Queue8 {
//  定义一个max,表示共有多少个皇后
    int max =8;  //8*8的棋盘,有8个皇后
    int[] array = new int[max];  //定义数组,存放皇后存在的位置
    int count =0;
    public static void main(String[] args) {
//        测试
        Queue8 queue8 = new Queue8();
        queue8.check(0);





    }

//   编写放置皇后的方法(n从0开始计数)
//  check每一次递归时进入到check都会有for循环,可以理解为多层for循环,这个想法太好了
    private void check(int n){
        if(n == max){
            count++;
            System.out.println(count);
            print();  //我们自己编写的,输出
//          //n=8,表示对数组来说就是第九个,很显然已经超出范围了,故我们的棋盘已经找出结果了
            return;
        }
//      依次放入皇后,并判断是否冲突
        for(int i=0;i<max;i++){
//          放置当前皇后n,放到改行的第一列
//          第n行第i列
            array[n] =i;
//          我们应该判断一下,第n行第i列放了行不行
            if (judge(n)){
//              运行到这里说明不冲突,然后再放下一个
                check(n+1);  //for循环结束或者n==max之后,就会产生回溯
            }
//          上面是不冲突的,万一冲突怎么办?
//              就会i++,又放到此行的下一个位置再次重试
        }

    }



    /**
     * 查看当我们放置第n个皇后,就去检测该皇后是否与前面已经摆放的皇后冲突
     *    这个地方我们不需要判断是否在同一行,因为我们使用了数组,数组下标代表行,故每行只能放一个
     *  n从零开始计数
     * @param n  表示第几个皇后
     * @return
     */
     private  boolean judge(int n){
        for(int i=0;i<n;i++){
            if(array[i]==array[n] ||Math.abs(n-i)==Math.abs(array[n]-array[i])){
//               array[i]==array[n]  表示在同一列
//               Math.abs(n-i)==Math.abs(array[n]-array[i])表示判断第n个皇后是否和第i皇后在同一个斜线上
//                  其实最后一个很好理解   把上面的式子变形,我们带入一下初中学的平面直角坐标系,
//                  (n-i)/(array[n]-array[i]) = -1 或1  通俗的来说就行y的变化量比上x的变化量等于正一或负一
//                  这样就是在同一个斜线上,这个地方真的有点巧妙
                return  false;
            }
        }
//      返回true说明冲突
        return true;
     }



//  写一个方法,可以将皇后摆放的位置输出
    private void print(){
        for(int i=0; i<array.length;i++){
            System.out.print(array[i]+"");
        }
        System.out.println();
    }
    
}

 

我们可以仔细的看一下下面这个图,我们看下标为0的数,是从0开始逐渐增大的,说明我们在分析阶段分析的没毛病。先把皇后在第一行的所有情况都找到,然后再把第二行的所有情况都找到,就这样依次执行到第八行,最终完成

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/93332.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Efficient Zero-shot Event Extraction with Context-Definition Alignment论文解读

Efficient Zero-shot Event Extraction with Context-Definition Alignment code&#xff1a;tencent-ailab/ZED: This is the repository for EMNLP 2022 paper “Efficient Zero-shot Event Extraction with Context-Definition Alignment” (github.com) paper&#xff1a;…

【手把手】分布式定时任务调度解析之Elastic-Job

1、这货怎么没怎么听过 经常使用Quartz或者Spring Task的小伙伴们&#xff0c;或多或少都会遇到几个痛点&#xff0c;比如&#xff1a; 1、不敢轻易跟着应用服务多节点部署&#xff0c;可能会重复多次执行而引发系统逻辑的错误&#xff1b; 2、Quartz的集群仅仅只是用来HA&…

业主应该重视装修中的“道”而不是“术”!极家精工装修好不好!

业主应该重视装修中的“道”而不是“术”&#xff01;极家精工装修好不好&#xff01;看了很多业主问了很多关于装修中很琐碎的事儿&#xff0c;比如“装修流程”、“装修应该注意什么”、“装修哪些必须要重视”、“某某材料和某某材料相比哪个好”、“家里装了什么是你最不后…

Lua中的基本数据类型

Lua中的数据类型一、Lua基本数据类型1.1、nil1.2、boolean1.3、number1.4、string1.5、function1.6、table二、Lua 通用数据结构的实现总结后言Lua是一门动态类型的脚本语言&#xff0c;这意味着同一个变量可以在不同时刻指向不同类型的数据。Lua代码中 一般采用一下两种做法相…

Dubbo-admin+Zookeeper 的环境搭建实操与 Could-not-extract-archive 报错踩坑

$ brew install zookeeper > Downloading https://homebrew.bintray.com/bottles/zookeeper-3.4.13.mojave.bottle.tar.gz ...先来看dubbo-admin的安装&#xff1b;我们先找到它在apache下的官方GitHub&#xff0c;官方也有相关介绍&#xff0c;中英文版都有(毕竟原本是中国…

[附源码]Node.js计算机毕业设计高校学科竞赛管理系统Express

项目运行 环境配置&#xff1a; Node.js最新版 Vscode Mysql5.7 HBuilderXNavicat11Vue。 项目技术&#xff1a; Express框架 Node.js Vue 等等组成&#xff0c;B/S模式 Vscode管理前后端分离等等。 环境需要 1.运行环境&#xff1a;最好是Nodejs最新版&#xff0c;我…

Kibana使用

简介 Kibana是通向 Elastic 产品集的窗口。 它可以在 Elasticsearch 中对数据进行视觉探索和实时分析。 Kibana通常用于项目log日志收集分析、数据可视化分析等。 一、【Discover】搜索查询 Discover模块用于全文搜索文档(doucument),支持索引筛选、时间筛选、字段筛选、支持…

linux下syslog使用说明

syslog 系统日志应用 1) 概述 syslog是Linux默认的日志守护进程。默认的syslog配置文件是/etc/syslog.conf文件。程序&#xff0c;守护进程和内核提供了访问系统的日志信息。因此&#xff0c;任何希望生成日志信息的程序都可以向 syslog 接口呼叫生成该信息。 几乎所有的…

读《深入浅出MySQL数据库开发、优化与管理维护(第2版)》笔记1

上面3图是书中MySQL帮助的使用小节; 实测: 我用DATE_FORMAT(date,format)函数的时候经常会记不清格式化的字符是啥,这个时候我会去求助度娘,然后从零散的帖子里找一个合适的,测试一下可用,就拿来用了,但没法马上找到一个比较完整系统一点的帖子,从看此书本章节,可知使用MySQL的…

acm是什么?你准备好去打了吗?

1.引言2.acm究竟是什么&#xff1f;3.acm的时间安排重点网络赛的作用1.名额分配2.校内选拔icpc省赛省赛选拔赛(校内)4.acm该如何准备1.前期的算法积累1.Acwing 平台算法基础课 -y总业界良心。算法提高课 基本囊括了蓝桥杯的知识范畴算法进阶课&#xff08;选&#xff09; 算法中…

MYSQL 8.0 -- 事务中删除不存在的记录导致死锁

最近开发的某个功能中&#xff0c;线上偶尔会爆出死锁异常。再大佬同事的帮助下&#xff0c;最终排查出了原因&#xff0c;在此记录一下。 文章目录业务描述事务中删除行时锁的表现场景重现问题处理业务描述 在业绩信息维护中&#xff0c;可以维护相关人员列表&#xff0c;相关…

谁再问我 Kafka,我把这 43 张图甩给他

从Kafka诞生的早期&#xff0c;我就对Kafka投入了很多的关注&#xff0c;虽然不敢说精通Kafka, 但也算是非常熟悉了。 平时在工作之中&#xff0c;几乎天天都在跟这玩意儿打交道&#xff0c;在面试的时候&#xff0c;也会经常聊一些Kafka相关的内容。 Kafka 是一个优秀的分布…

二苯并环辛炔-二硫键-马来酰亚胺,DBCO-SS-Maleimide,DBCO-SS-Mal

基础产品数据&#xff08;Basic Product Data&#xff09;&#xff1a; CAS号&#xff1a;N/A 中文名&#xff1a;二苯并环辛炔-二硫键-马来酰亚胺 英文名&#xff1a;DBCO-SS-Maleimide&#xff0c;DBCO-SS-Mal 详细产品数据&#xff08;Detailed Product Data&#xff09;&am…

C++--数据结构--并查集--高阶0711

1. 并查集 在一些应用问题中&#xff0c;需要将n个不同的元素划分成一些不相交的集合。开始时&#xff0c;每个元素自成一个 单元素集合&#xff0c;然后按一定的规律将归于同一组元素的集合合并。在此过程中要反复用到查询某一 个元素归属于那个集合的运算。适合于描述这类问…

如何使用Python批量化处理Excel——零基础入门指南

本教程旨在帮助零编程基础&#xff0c;但是又有“批量化处理Excel表”这种需求的大家。 在进入教程时&#xff0c;请确保你具有以下资质&#xff1a; 1、 并非工作压到头上了&#xff0c;急需解决一批表所以想过来速成&#xff0c;而是愿意耐心花上几个小时学习来获得一项长久…

Redis之相关拓展(事务、监控、Jedis)

Redis之相关拓展一、事务1、介绍2、流程3、shell命令3.1 开启事务3.2 放弃事务3.3 编译型异常&#xff08;代码有问题&#xff0c;命令有错&#xff09;3.4 运行时异常二、监控&#xff08;watch&#xff09;1、锁1.1 悲观锁1.2 乐观锁2、注意2.1 原理2.2 流程三、Jedis1、简介…

学习Opencv不得不掌握的操作

OpenCV基本操作 1 图像的IO操作 这里我们会给大家介绍如何读取图像&#xff0c;如何显示图像和如何保存图像。 1.1 读取图像 API cv.imread() 参数&#xff1a; 要读取的图像读取方式的标志cv.IMREAD*COLOR&#xff1a;以彩色模式加载图像&#xff0c;任何图像的透明度都将…

C++ Primer笔记——explicit、string流、vector比较、emplace

目录 一.P265 抑制构造函数定义的隐式转换 二.P287 string流 三.P304 vector的比较 四.P307 在容器中特定位置添加元素 一.P265 抑制构造函数定义的隐式转换 举个例子&#xff0c;如果构造函数参数是string类型&#xff0c;那么当使用赋值符号进行初始化操作时&#xff0c…

leetcode -- ⽤最少数量的箭引爆⽓球(452)

有一些球形气球贴在一堵用 XY 平面表示的墙面上。墙面上的气球记录在整数数组 points &#xff0c;其中points[i] [xstart, xend] 表示水平直径在 xstart 和 xend之间的气球。你不知道气球的确切 y 坐标。 一支弓箭可以沿着 x 轴从不同点 完全垂直 地射出。在坐标 x 处射出一…

数据模型篇之阿里巴巴数据整合及管理体系

第9章 阿里巴巴整合及管理体系 OneData的设计是为了建设统一的、规范化的数据接人层&#xff08; ODS &#xff09;和数据中间层&#xff08; DWD和DWS &#xff09;&#xff0c;通过数据服务和数据产品&#xff0c;完成服务于阿里巴巴的大数据系统建设 &#xff0c;即数据公共…