我试图弄清楚这个算法是否是A *(A-Star)算法或其他什么,但我仍然感到困惑。
Stack<Cell> stack = new Stack<>();
stack.push(maze.start());
stack.peek().mark(SOLUTION_MARK);
while (!stack.peek().hasMark(Cell.END)) {
Cell current = stack.peek();
ArrayList<Cell> dirs = current.neighbors();
boolean found = false;
for (Cell next : dirs) {
if (next.hasMark(ERROR_MARK) || next.hasMark(SOLUTION_MARK)) {
continue;
}
stack.push(next);
next.mark(SOLUTION_MARK);
found = true;
break;
}
if (!found) {
stack.pop().mark(ERROR_MARK);
}
for (MazeBody listener : listeners) {
listener.repaint();
}
}
Mark.java
public final class Mark {
private static Map<String, Mark> TABLE = new HashMap<>();
private String name;
private Mark(String markName) {
name = markName;
}
public static Mark get(String name) {
Mark mark = TABLE.get(name);
if (mark == null) {
mark = new Mark(name);
TABLE.put(name, mark);
}
return mark;
}
}
答案 0 :(得分:4)
这是 Depth First Search迭代编写而不是递归。
递归DFS(预订单)伪代码如下所示:
visit (current node)
for each child node of current node
if node is not explored
dfs (node)
DFS的迭代版本如下:
Put current node on stack
In a while loop pop the stack if not empty
visit (popped node)
push all Unvisited and NotVisiting neighbors of popped node on the stack
End while
迭代版本中的Unvisited和NotVisiting 表示该节点既没有被访问过,也没有被访问过。
此算法的时间复杂度取决于图表是否已存储为邻接列表或邻接矩阵。对于列表,它是O(n)。对于矩阵,它变为O(n 2 ),因为即使您只探索每个节点一次,您也必须访问矩阵的每一行和每列以确定它们之间是否存在路径节点X和节点Y。
此算法的空间复杂度可能会达到最差的O(n),当图表中的每个节点只有一个邻居时,就会发生变化,就像单个链表一样。
答案 1 :(得分:3)
根据您展示的内容,我会说它是深度优先搜索,但是检查该地点是否已安排访问。由于它使用堆栈,因此它将始终首先访问搜索树中更深的位置。但是从它向堆栈添加一个位置的那一刻起,它就将该位置标记为一个解决方案标记,以防止在另一条路径到达同一位置时重新评估。
但是请注意,它会将每个图块标记为SOLUTION_MARK
,除非它无法提供除标有SOLUTION_MARK
或ERROR_MARK
以外的节点。因此,它将比有助于(最短)解决方案的瓦片标记更多的瓦片。从这个意义上说,它实际上并不是一个迷宫解决算法:如果至少还有另一个尚未安排SOLUTION_MARK
。如果已标记所有可到达的图块,则算法将完成。