What kind of maze Solving Algorithm is this? - java

I am trying to figure out if this algorithm is A* (A-Star) Algorithm or whatever but still I am confused.
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;
}
}

This is Depth First Search written iteratively rather than recursively.
Recursive DFS (preorder) pseudocode looks like:
visit (current node)
for each child node of current node
if node is not explored
dfs (node)
Iterative version of DFS looks like:
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 and NotVisiting in the Iterative version means that the node is neither visited before, nor it is in the stack for visiting.
The time complexity of this algorithm depends on whether the graph has been stored as adjacency list or adjacency matrix. For list, it'd be O(n). For matrix, it'd become O(n2) because even though you explore every node only once, you have to visit every row and column of the matrix to know if there is a path between a node X and node Y.
The space complexity of this algorithm can go to worst of O(n), happening when the graph would have each node having only one neighbor, becoming like a singly linked list.

Based on what you show I would say it is depth-first search, but with a check whether the place has already been scheduled for visit. Since it uses a stack, it will always first visit the places deeper in the search tree. But from the moment it adds a place to the stack, it marks the place as a solution mark to prevent it from being re-evaluated if another path would reach the same place.
Note however that it will mark every tile a SOLUTION_MARK unless it cannot come up with nodes others than marked with a SOLUTION_MARK or an ERROR_MARK. It will thus mark more tiles than the tiles contributing to (shortest) the solution. In that sense it is not really a maze solving algorithm: it simply marks tiles as SOLUTION_MARK if there is at least another tile not yet scheduled that can contribute to a solution. The algorithm will finish if it has marked all reachable tiles.

Related

How do I find a certain node of a binary tree, using recursion?

How do I write the code to find a certain node. Specifically how do I say a node was visited after I check it?
public Iterator<T> pathToRoot(T targetElement, BinaryTreeNode<T> current)
throws ElementNotFoundException
{
Stack<BinaryTreeNode<T>> myStack = new Stack<>();
if (current == null)
return null;
if (current.element.equals(targetElement)) //found it
{
myStack.push(current); //adds the current element to the stack
}
// mark as visited
//mark node also as found
// return the found element
if (current.hasLeftChild() || current.hasRightChild()) //if the current node has a left or right child
{
// mark node as visited
}
if (current.hasLeftChild())//if the current node has a left child node
pathToRoot(targetElement, current.getLeft()); // check the left child node
if (current.hasRightChild())//same thing as above but for the right
pathToRoot(targetElement, current.getRight());
if(current != targetElement && /*node has been visited*/)
myStack.pop(); // pop node from the stack
return myStack.toString(); //return string of path to root
}
/using a dfs search to find a node/
The sole purpose of marking a graph node as visited is to make sure you won't get into an infinite loop, because a graph can contain a cycle.
A binary tree is a special kind of a graph, that doesn't contain cycles, therefore there's no need to mark nodes as visited when you're doing traversal.
Also, usually binary trees are ordered in a way that the current node contains value X, its left sub-tree has nodes that have values less than X, and its right sub-tree has nodes that have values greater than X. This allows having searches that take logarithmic time, in your demonstrated code you don't seem to utilize that.
So, I think you don't have a good understanding of how binary trees work and you should research a little more, before implementing this functionality.

Is it possible to print each level of a binary tree on a separate line using depth-first traversal?

I am familiar with the use of a queue to print each level in a separate line in O(n) time. I want to know if there is any way to do this using pre-order, in-order or post-order traversal. I have following code but I have no idea what to do with depth parameter. Only idea I have is using an array of linked lists to store all nodes while traversing the tree, consuming O(n) extra space. Is there any better way to do this?
class Node {
int key;
Node left;
Node right;
Node(int value) {
key = value;
left = null;
right = null;
}
}
public class bst {
private Node root;
bst() {
root = null;
}
private void printTreeRec(Node root, int depth) {
if(root != null) {
System.out.println(root.key);
printTreeRec(root.left, depth + 1);
printTreeRec(root.right, depth + 1);
}
}
void printTree() {
printTreeRec(root, 0);
}
public static void main(String[] Args) {
bst tree = new bst();
tree.insert(25);
tree.insert(15);
tree.insert(35);
tree.insert(7);
tree.insert(18);
tree.insert(33);
tree.insert(36);
tree.printTree();
}
}
It is not possible with the mentioned approaches indeed because they go depth-first that is they always go in a direction until they reach the end of the branch.
Or at least not with printing the output directly on the console, as the algorithm executes.
This is not a rigorous proof but it shall describe the issue:
Preorder
System.out.println(root.key);
printTreeRec(root.left, depth + 1);
printTreeRec(root.right, depth + 1);
At a particular node you print the current node first. Then, you go left, and you print that node, and so on. As you have already moved down the console, and you can't go back, this approach won't work
Inorder
printTreeRec(root.left, depth + 1);
System.out.println(root.key);
printTreeRec(root.right, depth + 1);
In this case you start at the root, and you go left. Still left, until there are no more children nodes. And then you print. But now you will go up the tree, and what will you do with the focus on the console line? Once again you have to move forward. Also not possible in this case.
Postorder
printTreeRec(root.left, depth + 1);
printTreeRec(root.right, depth + 1);
System.out.println(root.key);
In this case you start at the root, and you go left. Until you can. When you can't you start going right. Go right until you can. Then start printing. But now, similarly as above, you will go up the tree, and what will you do with the focus on the console line? Once again you have to move forward. Not possible again.
How can we make it work?
We should cheat, and pass a level variable to know the level at which we are at a particular moment. Fill a data structure, like map, that will contain node values per level, and after the algorithm is finished computing, print the result, one level per line, using the map.
You can reference the discussion at here: Java DFS solution. Post the code below for the convenience.
public List<List<Integer>> levelOrder(TreeNode root) {
List<List<Integer>> res = new ArrayList<List<Integer>>();
levelHelper(res, root, 0);
return res;
}
public void levelHelper(List<List<Integer>> res, TreeNode root, int height) {
if (root == null) return;
if (height >= res.size()) {
res.add(new LinkedList<Integer>());
}
res.get(height).add(root.val);
levelHelper(res, root.left, height+1);
levelHelper(res, root.right, height+1);
}

Homework: Return the least element in the set greater than given element BST

So I've been stuck for hours trying to figure out this problem.
Given a randomly generated BST and using the method header:
public E higher(E elt)
Where elt is a randomly generated value within the tree's range, I need to find the least element in the set greater than elt.
Nodes contain left links and right links, but no parent link.
The tree in the linked image reads with the root being the leftmost node
BST.
So if elt is 27, then I want to return the node containing 28.
I need to run this in O(logn) time, and everything I've tried has not worked.
I'm not looking for someone to do my homework for me, but I have no clue what to do at this point.
I can provide more detail and source code if it's needed.
Edit: I'll put this here, though it's woefully inadequate. I feel as though this would be easier if I could do this recursively but I can't think of a way to do that.
Node n = root;
//need to get this into a loop somehow and break out when I've found
//the right value
int c = myCompare(elt, ((E) n.data));
if (c < 0) {
n = n.left;
//now I need to compare this against any children
} else if (c > 0) {
n = n.right;
//now I need to compare this against any children
}
return ((E)n.data);
This depends on the fundamental property of BSTs: the left child is less than the parent, the right child is greater than the parent. If you look at a sample BST you will quickly notice a few properties, and you can see why the following algorithm will work.
If the current node is less than the given value, move right, otherwise move left. If you reach a point where moving left will give you a value that is too low (or you hit a leaf) then you found the correct node. Or, in pythonic pseudo-code:
while (true):
if (node.value <= elt):
node = node.right
else:
if (node.left.value < elt):
return node.value
else:
node = node.left
The pseudo-code obviously needs to check for errors, if a node is a leaf, etc., but this general algorithm will give you the expected output in the desired time complexity (assuming a balanced BST).
One possible approach is to find the specified node and to get the next least node from there (if you're allowed to use helper methods).
If we say that the root node is 'n' and we know that the desired value is inside the BST, then you can traverse through it to find the node that contains the given value with something like this:
public Node search(Node n, E obj)
{
if(obj.compareTo(n.getValue()) > 0)
{
return search(n.getRight(), obj);
}
else if(obj.compareTo(n.getValue()) < 0)
{
return search(n.getLeft(), obj);
}
else
{
return n;
}
}
If the objective were to retrieve the least value from a binary search tree, a simple recursive method like this would work:
public Node getLeast(node n)
{
if(n.getLeft()==null)
{
return n;
}
return getLeast(n.getLeft());
}
Using the principles of a binary search tree, we know that the least value greater than a given node is just the least node after the right child of the given node. So, we can just use this method to obtain the desired value:
getLeast(search(n,elt).getRight());

Building a linked list as the basis of a graph Null pointer errors

I am trying to build a graph based on a linked list, where I build the linked list of nodes, and each node points to a linked list of edges. I build the graph based on an input file.
My input file will be on the following scheme:
Number of Nodes in graph
SourceNode1 EndNode1
SourceNode2 EndNode2
....
For example:
4 //Number of nodes
1 2 //An edge between 1 and 2
1 3 //An edge between 1 and 3
2 4 //An edge between 2 and 4
An assumption is that the nodes in the graph will numbered 1 through the number of nodes and that no node will have more than 1 "parent" (though a node might have more than 1 "child").
My problem is trying to build the linked list containing the nodes. Each node has 3 fields: the edges coming from that node, the node value (1, 2, 3, etc.), and the next node (because is a linked list of nodes). I attempt to parse in the number of nodes, create a first node manually, and attach the rest of the nodes in an in an iterative fashion.
Note: The parent field is for some external analysis unrelated to this question. You can ignore it.
Node class:
public class Node {
private Edge firstEdge;
private Node parent;
private Node nextNode;
private int element;
//Constructor
public Node() {
parent = null;
firstEdge = null;
nextNode = null;
}
//Accsessor and Modifier Methods
public void setElement(int e) {element = e;}
public Node getNextNode() {return nextNode;}
public Edge getFirstEdge() {return firstEdge;}
public void setFirstEdge(Edge a) {firstEdge = a;}
public void setNextNode(Node a) {nextNode = a;}
public int getElement() {return element;}
public Node getParent() {return parent;}
public void setParent(Node p) {parent = p;}
//Checks for a non-null parent
public boolean hasParent() { return parent == null; }
//checks iff node has next edge
public boolean hasFirstEdge() { return firstEdge == null; }
//checks if a node has a next node
public boolean hasNextNode() { return nextNode == null; }
}
Edge class:
public class Edge {
//Instance Variables
private Node nextNode;
private Edge nextEdge;
//Constructor
public Edge() {
nextNode = null;
nextEdge = null;
}
//Accsessor and Modifier Methods
public void setNextNode(Node a) {nextNode = a;}
public void setNextEdge(Edge a) {nextEdge = a;}
public Node getNextNode() {return nextNode;}
public Edge getNextEdge() {return nextEdge;}
public boolean hasNextEdge() {
return nextEdge == null;
}
}
Driver class:
import java.util.Scanner;
import java.io.*;
public class Driver {
public static void main(String[] args)throws FileNotFoundException{
//Get text file for building the graph
Scanner console = new Scanner(System.in);
System.out.print("Please enter the text file name: ");
String fileName = console.nextLine();
Scanner in = new Scanner(new File(fileName));
//in contains the file reading scanner
int numNodes = in.nextInt(); //first line of the text file
Node first = new Node(); //first is head of the list
first.setElement(1);
int i = 2; //counter
//Build the nodes list; I get problems in this loop
while (i <= numNodes) {
Node head = new Node(); //Tracker node
head = first; //head is the first node of the list
/*Loop to end of the list*/
while(head.hasNextNode()) {
//Null check; without it, I get NullPointerExceptions.
//If it is not needed, or there is a better way, please inform me.
if (head.getNextNode() == null) {
break;
}
head = head.getNextNode(); //get to the end of the ilst
}
//Next node to add
Node newNode = new Node();
newNode.setElement(i); //Because of the 1, 2, 3 nature of the graph
head.setNextNode(newNode); //Set the last element as the next node
i++;
}
//Manually check if graph is made (check if the nodes are linked correctly)
System.out.println("First elem (expect 1): " + first.getElement());
System.out.println("Second elem (expect 2): " + first.getNextNode().getElement()); //It prints 4 here for some reason
System.out.println("Third elem (expect 3): " + first.getNextNode().getNextNode().getElement()); //Getting a NullPointerException
System.out.println("Fourth elem (expect 4): " + first.getNextNode().getNextNode().getNextNode().getElement());
System.out.println("Expecting null: " + first.getNextNode().getNextNode().getNextNode().getNextNode().getElement());
}
When I'm checking if the graph is built, I get problems. I am manually checking it (for this small graph, its possible), and simply print out the first node and the value of the subsequent nodes. I am expecting 1, 2, 3, 4, and null (for the element past 4, because it does not exist). The first node is fine, it prints 1. Calling first.getNextNode().getElement() prints 4, for some odd reason. And calling the node after that gives a NullPointerException. Could someone help me solve this problem?
Note: I haven't added the edges yet. I am just trying to get the core of the linked list of nodes built.
This is my first post on stack overflow. I apologize if it is vague, ambigous, overly detailed, lacking in information, or is a duplicate question. I could not find the answer anywhere else. All input is welcome and appreciated.
Much of your naming is very confusing and is in serious need of clarifying refactorization. Edge's nextNode should be called destinationNode or something along those lines to make it clear you are dereferencing from an Edge object instead of from another Node.
Now, let's delve into the actual implementation.
Node head = new Node(); //Tracker node
head = first; //head is the first node of the list
What's going on here? It looks like you set your local variable head to be a brand new Node; that's great. Except the very next line, you discard it and set it to the value of your first variable.
Then you traverse all the way to the end of the list with a while loop, then create another new Node (this one you actually use). (Normally if you wanted to add something to the end of the list you should be utilizing a doubly linked list, or should at least have pointers to both the first and the last elements... i.e., first always stays the same, but when you add a new node you simply say newNode = new Node(); last.nextNode = newNode; last = newNode; and then configure the new element from there. The way you are doing it, it's taking O(N^2) time to construct a singly-linked list with N elements, hardly ideal.
I also have some preferential criticism about the construction of your minor classes... if you are allowing values to be freely get and set to any value with public setters and getters without taking any action whatsoever when they change, you get the exact same functionality from simply marking those fields public and doing away with the getters and setters entirely. If you have any plans to add more functionality in the future it's fine the way it is, but if they are just going to be dumb linked list elements whose actual uses are implemented elsewhere then you are better off treating the class more like a struct.
Here's a good way to build a singly-linked Node list the way you're looking to:
int numNodes = in.nextInt(); //first line of the text file
// sentinel value indicating the beginning of the list
Node header = new Node();
header.setElement(-1);
// last node in the list
Node last = first;
// this loop constructs a singly linked ring from the header
for (int i = 1; i <= numNodes; i++) {
Node newNode = new Node();
newNode.setElement(i);
newNode.setNextNode(header);
last.setNextNode(newNode);
last = newNode;
}
// do your debug outputs here
// for instance, this loop always outputs every node in the list:
for (Node n = header.getNextNode(); n != header; n = n.getNextNode()) {
System.out.println("Node " + n.getElement());
}
Note that the use of header as a sentinel value guarantees that for any Node that's already been built, getNextNode() will never return null.
Again, all this code can be made much more readable by making the fields in your Node and Edge classes public and scrapping the getters and setters. header.getNextNode().getNextNode().getNextNode() can become header.nextNode.nextNode.element and so forth.
Stage 2
Now that that's out of the way, we have the question of how useful this type of structure will actually be for your application. My biggest concern in looking at this is the fact that, when applying edges between nodes on your graph, you will need to access arbitrarily indexed Nodes to attach edges to them... and while every Node already knows what its element index is, getting the Nth node takes N steps because your entire set of nodes is in a linked list.
Remember, the main advantage of using a linked list is the ability to remove arbitrary elements in O(1) time as you step through the list. If you are only building a list and aren't going to ever remove anything from it, arrays are often faster -- especially if you ever need to access arbitrary elements.
What if you don't need to guarantee they're in any particular order or access them by their index, but you need to be able to add, access-by-ID, and remove them very quickly for larger data sets? HashSet may be the thing for you! What if you still need to be able to access them all in the order they were added? LinkedHashSet is your best friend. With this, you could easily even give the nodes names that are strings with no real slowdown.
As for the edges, I feel you are already doing fine: it's probably best to implement the outgoing edges for each Node in a singly linked list, assuming you will rarely be removing edges or will have a small number of edges per node and will always access them all together. To add a new edge, simply say newEdge = new Edge(); newEdge.nextEdge = firstEdge; firstEdge = newEdge; and you're done, having added the new edge to the beginning of the list. (Singly linked lists are easiest to use as stacks rather than queues.)
For extra fancy-points, implement Iterable<Edge> with your Node class and make a little Iterator class so you can use extended-for to visit every edge and make your life even easier!
As #Widdershins says, the terms used makes the algorithm hard to understand.
I would recommend two things in order to refactor your code:
Review the terminology (maybe this helps: http://en.wikipedia.org/wiki/Glossary_of_graph_theory). I know that it sounds like a silly recommendation, but using proper terms will help you a lot to review the object model.
Use a better representation. In your code a Node fills multiple roles, which makes the code hard to follow.
A good representation will depend a lot of the kind of problems that you try to resolve. For example an Adjacency List, or a Matrix are useful to apply some algorithms of graph theory.
But if you only want to exercise with an object oriented design, is useful to start with the basics.
Take the definition of a Graph in mathematics: G = (V, E)... a graph is a pair of a set of nodes and a set of edges between those nodes, and translate it to code:
(the example uses fields for brevity)
class DirectedGraph {
final Set<Node> nodes = new HashSet<Node>();
final Set<Edge> edges = new HashSet<Edge>();
}
Now you need to extend this definition. You can do it step by step. I did the same to end with this representation:
class DirectedGraph {
final Set<Node> nodes = new HashSet<Node>();
final Set<Edge> edges = new HashSet<Edge>();
public Node addNode(Object value) {
Node newNode = new Node(value);
nodes.add(newNode);
return newNode;
}
public Edge addEdge(Node src, Node dst) {
Edge newEdge = new Edge(src, dst);
edges.add(newEdge);
return newEdge;
}
private assertValidNode(Node n) {
if (n.graph != this)
throw new IllegalArgumentException("Node " + n + " not part of the graph");
}
public Set<Node> successorsOf(Node n) {
assertValidNode(n);
Set<Node> result = new HashSet<Node>();
for (Edge e : edges) {
if (e.src == n) { result.add(e.dst); }
}
return result;
}
class Node {
final graph = DirectedGraph.this;
final Object value;
Node(Object v) {
this.value = v;
}
public String toString() { return value.toString(); }
public Set<Node> successors() {
return graph.successorsOf(this);
}
// useful shortcut
public Node connectTo(Node... nodes) {
for (Node dst : nodes) {
graph.addEdge(this, dst);
}
return this;
}
}
class Edge {
final graph = DirectedGraph.this;
final Node src; final Node dst;
Edge(Node src, Node dst) {
graph.assertValidNode(src);
graph.assertValidNode(dst);
this.src = src; this.dst = dst;
}
public String toString() { return src.toString() + " -> " + dst.toString(); }
}
}
DirectedGraph g = new DirectedGraph();
DirectedGraph.Node one = g.addNode(1);
DirectedGraph.Node two = g.addNode(2);
DirectedGraph.Node three = g.addNode(3);
DirectedGraph.Node four = g.addNode(4);
one.connectTo(two, three)
two.connectTo(four);
System.out.println(g.edges);
System.out.println(one.successors());
System.out.println(two.successors());
This strategy of representing the domain model in a "1 to 1" mapping, always helped me to "discover" the object model. Then you can improve the implementation for your specific needs (i.e. the running time of successorsOf can be improved by using an adjacency list).
Note that in this representation a Node and an Edge can only exist as a part of a graph. This restriction is not deduced directly from the math representation... but helps to maintain the constraints of a proper graph.
Note You can extract the inner-classes by constructing the Node and Edge with a parent graph reference.

How to find the depth of a tree iteratively in Java?

In an interview, I was asked to find the depth of the tree. I did it recursively, but then interviewer asked me to do it using iteration. I did my best, but i don't think he looked quite convinced. can anyone write the pseudo-code here or code would be preferable...Thanks for reading the post.
Check the answer provided at Way to go from recursion to iteration. Bottom line is that you don't have to solve the problem twice. If you have a perfectly good recursive algorithm, then transform it into an iteration.
Tree<Object> tree = ...; // source
class NodeMarker {
public NodeMarker(TreeNode node, int depth) { ... }
public TreeNode node;
public int depth;
}
int depth = 0;
List<NodeMarker> stack = new LinkedList<NodeMarker>();
for (TreeNode node : tree.getChildren())
stack.add(new NodeMarker(node, 1);
while (stack.size() > 1) {
NodeMarker marker = stack.get(0);
if (depth < marker.depth)
depth = marker.depth;
if (marker.node.hasChildren())
for (TreeNode node : marker.node.getChildren())
stack.add(new NodeMarker(node, marker.depth + 1);
}
Iteration rather than recursion means that is you go down the tree, rather than having each function call spawn two new function calls, you can store each member of the layer in an array. Try starting with a (one element) array containing a pointer to the root. Then, in a loop (I'd just use a while (1)) iterate over that array (currentLayer) and create a new array (nextLayer) and add the children of each element in currentLayer to nextLayer. If nextlayer is empty, you're now at the deepest layer, otherwise increment depth by one, copy nextLayer to currentLayer, and do it again.

Categories