(注:日志类 Log 详见 http://blog.csdn.net/runninglion/article/details/46057643)
本示例程序主要用于实现利用栈走迷宫的功能,关于迷宫算法,请查看《数据结构》一书中的描述。
1. 位置描述类 Position,迷宫中的每个格子都是一个位置
package maze;
public class Position {
int x, y;
public Position() {
}
public Position(int x, int y) {
this.x = x;
this.y = y;
}
public void setX(int x) {
this.x = x;
}
public void setY(int y) {
this.y = y;
}
public int getX() {
return x;
}
public int getY() {
return y;
}
}
2. 迷宫描述类 Maze,代表迷宫本身,它带有寻找可行路径的 traverse() 方法
package maze;
import stack.LinkedStack;
import stack.StackADT;
public class Maze {
private final int TRIED = 3;
// private final int PATH = 7;
private int [][] grid = {
{1,1,1,0,0},
{1,0,1,1,1},
{0,1,0,0,1},
};
private StackADT<Position> pushNewPos(int x, int y,
StackADT<Position> stack) {
Position pos = new Position();
pos.setX(x);
pos.setY(y);
if(isValid(pos.getX(), pos.getY())) {
stack.push(pos);
}
return stack;
}
public boolean traverse() {
boolean isDone = false;
Position pos = new Position();
StackADT<Position> stack = new LinkedStack<Position>();
stack.push(pos);
while(!isDone) {
pos = stack.pop();
if(null == pos) {
isDone = false;
break;
}
grid[pos.getX()][pos.getY()] = TRIED;
if(pos.getX() == grid.length - 1
&& pos.getY() == grid[0].length - 1) {
isDone = true;
} else {
stack = pushNewPos(pos.getX(), pos.getY() - 1, stack);
stack = pushNewPos(pos.getX(), pos.getY() + 1, stack);
stack = pushNewPos(pos.getX() - 1, pos.getY(), stack);
stack = pushNewPos(pos.getX() + 1, pos.getY(), stack);
}
}
return isDone;
}
private boolean isValid(int row, int column) {
boolean ret = false;
if(row >= 0
&& row < grid.length
&& column >= 0
&& column < grid[row].length) {
if(1 == grid[row][column]) {
return true;
}
}
return ret;
}
public String toString() {
String ret = "\n";
for(int row = 0; row < grid.length; row++) {
for(int col = 0; col < grid[row].length; col++) {
ret += grid[row][col] + "";
}
ret += "\n";
}
return ret;
}
}
3. 辅助实现迷宫的栈的抽象数据类型 StackADT<T>
package stack;
public interface StackADT<T> {
public void push(T item);
public T pop();
public T peek(); // get the top item but not pop
public boolean isEmpty();
public int size();
public String toString();
}
4. StackADT<T> 的一个具体实现
package stack;
import util.Log;
public class LinkedStack<T> implements StackADT<T> {
private static final String LOG_TAG = LinkedStack.class.getName();
private int mCount;
private LinearNode<T> mTop;
@Override
public void push(T item) {
LinearNode<T> temp = new LinearNode<T>(item);
temp.setNext(mTop);
mTop = temp;
mCount++;
}
@Override
public T pop() {
if(isEmpty()) {
Log.error(LOG_TAG, "pop()", "try to pop from an empty stack!");
return null;
}
T ret = mTop.getElement();
mTop = mTop.getNext();
mCount--;
return ret;
}
@Override
public T peek() {
if(isEmpty()) {
Log.error(LOG_TAG, "peek()", "try to peek from an empty stack!");
return null;
}
return mTop.getElement();
}
@Override
public boolean isEmpty() {
return 0 == mCount;
}
@Override
public int size() {
return mCount;
}
/**
* LinearNode class
*/
public class LinearNode<T> {
private T element;
private LinearNode<T> next;
public LinearNode() {
next = null;
element = null;
}
public LinearNode(T elem) {
next = null;
element = elem;
}
public LinearNode<T> getNext() {
return next;
}
public void setNext(LinearNode<T> node) {
next = node;
}
public T getElement() {
return element;
}
public void setElement(T elem) {
element = elem;
}
}
}
5. 测试类 Main
package maze;
import util.Log;
public class Main {
private static final String LOG_TAG = Main.class.getName();
public static void main(String[] args) {
Maze mazePath = new Maze();
Log.info(LOG_TAG, "main()", mazePath.toString());
if(mazePath.traverse()) {
Log.info(LOG_TAG, "main()", "The maze was successfully traversed!");
} else {
Log.info(LOG_TAG, "main()", "There is no possible path!");
}
Log.info(LOG_TAG, "main()", mazePath.toString());
}
}