一:栈
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));
- }
- }
- }