A 6x7 maze. The green and red cells represent the start and end locations respectively. Black cells represent
walls and light blue represent open spaces.
Finding a path through a maze can be done with a simple depth first search algorithm
The high-level idea is simple
Pick a path not visited yet
Keep travelling down the path until the end or a dead end is found
If the end is found, done
If a dead end is found, backtrack until another available unvisited path is found
Repeat
The backtracking is handled by a stack
The top of the stack is the last thing (cell from a pathway) visited
The thing after/below the top is the second last thing (cell from a pathway) visited
…
Thus, backtracking is done by
Popping from the stack
Checking if the new top has any available unvisited paths
1Add the start of the maze to the stack
2 3While the stack is not empty
4 Get the top of the stack with a peek (current cell)
5 If the top is the end
6 done
7 8 If an unvisited neighbour of the current cell exists
9 Push the neighbour onto the stack
1011 Otherwise, if no admissible neighbour exists
12 Pop from the stack
1314If the loop ever exits because of an empty stack, there is no solution
Animation of a depth first search through a 6x7 maze. The green and red cells represent the start and end
locations respectively. Black cells represent walls and light blue represent open spaces. Purple represents the
current location in the maze (top of the stack), grey represent spaces in a pathway being explored (currently
within the stack, but not the top), and orange represents spaces that were part of a dead end path (popped from
the stack).
Try to see where the push, pop, and peek operations are happening
Again, notice that this algorithm was described with only the what of a stack
There was no need to know how the stack was implemented in order to use it to solve a problem
When creating an instance of the stack, the type is specified within the < and > symbols
This will be discussed more in the following topic
In the above example, with the use of generics
Three different stacks are created, each with a different type of object as its contents
Only one interface (and implementation) is needed for all three
Note
The inclusion of <Type> on the instantiation side is not actually needed as Java can infer the type. Going
forward, for simplicity, Java’s diamond operator (<>) will be used, like so:
It is not possible to use primitive types (int, double, boolean, etc.) in generics. Instead, use the
object version of the primitive type (Integer, Double, Boolean, etc).