栈和队列的底层实现及迷宫问题

一:栈

1.栈的应用背景

         栈是一种线性数据结构,并且只能在某一端存数据和取数据。

关键词:先进先出。

2.栈的两种实现方法:

2.1用ArrayList实现栈

具体代码如下:

import java.util.ArrayList;
public class ArrayListAsStack {
    ArrayList stack = new ArrayList();
    public ArrayListAsStack(int n){
       stack.ensureCapacity(n);
    }
    public void push(Object o1){
       stack.add(o1);
    }
    public Object pop(){
       return stack.remove(stack.size()-1);
    }
    public Object topEle(){
       return stack.get(stack.size()-1);
    }
    public boolean isEmpty(){
      
       return stack.isEmpty();
    }
    public void clean(){
       stack.clear();
    }
}

Pop:只用删除ArrayList中的最后一个元素

Push:在ArrayList中添加一个元素

2.2用LinkedList实现栈

代码如下:

import java.util.LinkedList;
public class LinkedListAsStack {
    LinkedList stack = new LinkedList();
    public void push(Object o1){
       stack.add(o1);
    }
    public Object pop(){
       return stack.removeLast();
    }
    public Object topEle(){
       return stack.getLast();
    }
    public boolean isEmpty(){
       return stack.isEmpty(); 
    }
    public void clean(){
       stack.clear();
    }
}

Pop:删除链表中最后一个节点

Push:在链表中添加一个节点

二:队列

         队列与栈的不同之处在于,队列的两端都有用到,数据从队列的尾部添加,从队列的头部取出。FIFO原则。

1.队列的实现

         与栈相同,队列可以通过array和linkedlist两种方式实现,在此不再累述。

2.优先队列

         队列的先进先出有时候会有一定的局限性。例如:银行办业务的客户必须按照“先进先出”的性质进行等待办理,但是有的客户持有的是金卡,则应该被有限办理。优先队列则用于处理这类的问题。

即优先队:数据的存入是按照先进先出的方式放进去的,但是存入的数据有对应的优先级,则取出的时候根据优先级取出。

三:用栈实现走迷宫

         老鼠走迷宫是栈的一个典型应用,如下,有一个简单的迷宫(m代表入口,e代表出口,0代表该路行得通,1代表墙):

1 1 0 0

0 0 0 e

0 0 m 1

思想:老鼠会尝试所有可行的路径(上、下、左、右四个方向),如果碰到了死角,则会返回到最后一步再尝试其他路径,所以上下左右方向的顺序会影响到最后寻找的出路。

实现:

我们将迷宫放在一个二维数组里,由于数组的计数从0开始,我们为了更直观,在初始二维数组周围加上2,如下

1 1 1 1 1 1

1 1 1 0 0 1

1 0 0 0 e 1

1 0 0 m 1 1

1 1 1 1 1 1

这里需要用到栈,将可能走的位置按照一定的规律压入栈中(例如上下左右),例如到了A的位置,则在A的基础上往下走,如果A后面没有可行的路径,则返回至A的上一步。下面详解实现。

(1)构建MazeCell:表示迷宫的位置

public class MazeCell {
    int x;
    int y;
    public MazeCell(){
      
    }
    public MazeCell(int a,int b){
       this.x = a;
       this.y = b;
    }
    public Booleanequals(MazeCell cell){
       if(cell.x == this.x&&cell.y==this.y)
           return true;
       else
           return false;
    }
}

(2)寻找出路的具体实现

public class Maze {
    //构建maze所需的参数
    char[][] maze = new char[5][6];
    char entrance = 'm';
    char exit = 'e';
    char pass= '0';
    char notPass='1';
    char visited = '2';
    //获得maze路径所需参数
    Stack<MazeCell> pushUnvisited = new Stack<MazeCell>();
    MazeCell currentCell = new MazeCell();
    MazeCell exitCell = new MazeCell(2,4);
    MazeCell entryCell = new MazeCell(3,3);
   
     public static void main(String[]args){
        Maze maze = new Maze();
        maze.makeMaze();
        maze.getPath();
     }
     
     //构造一个maze
     public void makeMaze(){
        //给迷宫外加上1
        for(int i = 0;i<6;i++){
           maze[0][i] =notPass;
           maze[4][i]=notPass;
        }
        for(int j = 0;j<5;j++){
              maze[j][0] =notPass;
              maze[j][5]=notPass;
            }
        maze[1][1] = notPass;
        maze[1][2] =notPass;
        maze[1][3] = pass;
        maze[1][4] = pass;
        maze[2][1] = pass;
        maze[2][2] =pass;
        maze[2][3] = pass;
        maze[2][4] =exit;
        maze[3][1] = pass;
        maze[3][2] =pass;
        maze[3][3] = entrance;
        maze[3][4] =notPass;
     }
     
     //寻找走出迷宫的路径
     public void getPath(){
        currentCell = entryCell;
        while(!currentCell.equals(exitCell)){
            int x = currentCell.x;
            int y = currentCell.y;
            //搜索路径为上下左右,不同的顺序会有不同结果
            pushStack(x-1,y);
            pushStack(x+1,y);
            pushStack(x,y-1);
            pushStack(x,y+1);
            //把走过的位置标记成visited
            if(!currentCell.equals(entryCell)){
                maze[x][y] = visited;
            }
            //如果在还没到达终点,栈就空了,说明该迷宫米有出路
            if(pushUnvisited.isEmpty()){
               System.out.println("failure");
               return;
            }
            //将当前位置往前移
            MazeCell tmp = pushUnvisited.pop();
            currentCell = tmp;
            //输出我走过的节点
            System.out.println(tmp.x+","+tmp.y);
        }
     }
     public void pushStack(int x ,int y){
        //如果是visited或notPass,则不能压进栈
        if(maze[x][y] == pass||maze[x][y]==exit){
            pushUnvisited.push(new MazeCell(x,y));
        }
     }
}

    原文作者:迷宫问题
    原文地址: https://blog.csdn.net/shanxing2/article/details/8099700
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞