数据结构-java-迷宫问题的队列实现

迷宫问题:

  • 用队列实现在一个数组组成的迷宫中寻找路径到出口

实现的思路:

  1. 使用队列实现,一种广度搜索
  2. 队列选用循环单链表为基础实现队列ADT
  3. 前进方向判断
  4. 遇到死路要回退, 链表的抽象节点类不方便满足需求,新建position节点类(新增prev域指向前驱)

1. 循环单链表为基础的队列

  • CircSinglyLinkedList.java
package indi.yyh.datastru.project2.CircleLink;

import indi.yyh.datastru.project2.Node;

// @author yyh

//循环单链表

public class CircSinglyLinkedList<T> extends Object {
     
    // 头结点
    public Node<T> head;		//next域和data,自个写,就不贴代码了
    public int length = 0;

    // 构造方法
    public CircSinglyLinkedList() {
     
        this.head = new Node<T>();
        this.head.next = this.head;
    }
  	public CircSinglyLinkedList(T[] values) {
     
        this();
        this.length = values.length;
        Node<T> rear = this.head;
        for (int i = 0; i < values.length; i++) {
     
            rear.next = new Node<T>(values[i], null);
            rear = rear.next;
        }
        rear.next = this.head;

    }

	//判空
    public boolean isEmpty(){
     
        return this.length== 0;
    }

    public int insert(int i, T x) {
     
        int count = 0;
        Node<T> q = new Node<T>(x, null);
        Node<T> p = this.head.next;
        while (count != i-1) {
     
            p = p.next;
            count++;
        }
        q.next = p.next;
        p.next = q;
        this.length++;
        return i; // 返回序列号
    }

    public int insert(T x) {
     
        return this.insert( this.length , x); // 默认尾插入
    }

    public boolean insertHead(T x) {
     		//头插法,修正指定位置插入中的i-1 = -1 的错误
        Node<T> q = new Node<T>(x, null);
        Node<T> p = this.head;
        q.next = p.next;
        p.next = q;
        this.length++;
        return true;
    }

    public T remove(int i){
     
        Node<T> front = this.head;
        for(int j = 0; j<i ;j++){
     
            front = front.next;
        }
        T old = front.next.data;
        if(front.next.next!=null){
     
            front.next = front.next.next;
        }else{
     
            front.next = this.head;
        }
        this.length--;
        return old;
    }

    // 此处更改循环条件为 p!=this.head;
    public String toString() {
     
        String str = "(";
        for (Node<T> p = this.head.next; p != this.head; p = p.next) {
     
            str += p.data.toString();
            if (p.next != this.head) {
     
                str += ",";
            }
        }
        return str + ")";
    }
}

  • Queue.java
package indi.yyh.datastru.project3;
//ADT
public interface Queue<T> {
     

    public abstract boolean isEmpty();
    public abstract boolean add(T x);
    public abstract T peek();
    public abstract T poll();
    
}
  • ScQueue
public class ScQueue<T> implements Queue<T>{
     

    private CircSinglyLinkedList<T> list;

    //构造循环单链表队列
    public ScQueue(){
     
        this.list = new CircSinglyLinkedList<T>();
    }
    //实现circlesinglelist的方法.......

2. 使用position节点类记录当前位置

  • position.java
package indi.yyh.datastru.project3.maze;

//构建位置节点类
public class position<T> {
     
    public position<T> prev;
    public int x;
    public int y;

    public position(int x, int y, position<T> prev) {
     
        this.x = x;
        this.y = y;
        this.prev = prev;
    }

    public position(){
     
        this(1,1,null);
    }
}

3. 判断前进方向, 并实现路径入队出对操作

  • findLoad() //代码具体自行优化,老子时间有限,水平不高
  //规定出口,地图 , 1为墙, 0为路, 主函数实现自个写去>A<
  /*public static int EX = 3; // 定义出口的X坐标在第9行
  public static int EY = 5; // 定义出口的Y坐标在第11列
  public static int[][] maze = { 
    { 1, 1, 1, 1, 1, 1 }, 
    { 1, 0, 1, 0, 1, 1 }, 
    { 1, 0, 0, 0, 1, 1 }, 
    { 1, 0, 1, 1, 0, 0 },
    { 1, 0, 0, 0, 0, 1 }, 
    { 1, 1, 1, 1, 1, 1 }, 
  };*/

  public static String findLoad(int x, int y) {
     
    ScQueue path = new ScQueue(); // 用于存储迷宫路径

    position p = new position(); // 标记当前位置 x, y
    position pre = p;

    path.add(("(" + p.x + "," + p.y + ")"));

    while (x != EX || y != EY) {
     

      if (maze[x - 1][y] == 0) {
     
        pre = p;
        maze[x][y] = 2; // 状态(已走为2,未走为0,死路为-1)
        x -= 1;
        p = new position(x, y, pre);
        path.add(("(" + p.x + "," + p.y + ")"));

      } else if (maze[x][y + 1] == 0) {
     

        pre = p;
        maze[x][y] = 2;
        y += 1;
        p = new position(x, y, pre);
        path.add(("(" + p.x + "," + p.y + ")"));

      } else if (maze[x][y - 1] == 0) {
     

        pre = p;
        maze[x][y] = 2;
        y -= 1;
        p = new position(x, y, pre);
        path.add(("(" + p.x + "," + p.y + ")"));

      } else if (maze[x + 1][y] == 0) {
     
        pre = p;
        maze[x][y] = 2;
        x += 1;
        p = new position(x, y, pre);
        path.add(("(" + p.x + "," + p.y + ")"));

      } else {
      // 判断死路并回退

        maze[x][y] = -1;
        p = p.prev; // 将节点回退
        x = p.x; // 重置当前的位置为前一节点
        y = p.y;
        path.poll(path.size() - 1); // 尾部删除
      }
    }
    return path.toString();
  }

实现效果

数据结构-java-迷宫问题的队列实现_第1张图片
本人练习数据结构代码,没有怎么考虑优化,大佬勿喷,萌新仅供参考

你可能感兴趣的:(数据结构,数据结构,队列,java)