I tried to implement BFS algorithm in JAVA based on what I study but I'm confused a little, I'm not sure if I'm checking if the node is goal or I'm adding nodes to explored list in the appropriate place. Here's the code:
frontier.add(nodes.getFirst());//node.isGoal is only true if the node is desired node
if(frontier.getFirst().isGoal)//Checking if the root node is goal
{
explored.add(frontier.getFirst());
prev.put(frontier.getFirst(), null);
goalNode = explored.getFirst();
frontier.poll();
}
while (!frontier.isEmpty())
{
currentNode = frontier.poll();
explored.add(currentNode);
for (Node node : currentNode.children) {//adding node children to fronier and checking if they are goal
if (!frontier.contains(node) || !explored.contains(node)) {
frontier.add(node);
prev.put(node, currentNode);//mapping nodes to parent node to return sequence of nodes
if (node.isGoal) {
goalNode = node;
break;
}
}
}
}
Thanks in advance.
Based on how I understand your code it seems you're doing it wrong: you check the first node in your initial set (e.g. tree level) and if it is not the goal node you add any children that are not already in frontier and that have not been visited yet. That's ok but probably unnecessary. What's wrong is that you're checking the child before checking any of the parent's siblings so your search is not exactly breadth-first.
So what could/should you do?
Let's assume your data represents a tree (breadth-first indicates that) and you're starting at some level (e.g. the root node). Since the data is a tree in a breadth-first approach any child not cannot have been visited already and is also probably not in your frontier list so there's no need to check for that (if you have a more general graph that might not be the case).
Thus the algorithm could look like this:
LinkedList<Node> frontier = new LinkedList<>();
//assuming you always have a root node just add it
frontier.add( root );
Node goal = null;
//loop until the list is empty, if we found a goal node we'll break the loop from the inside
while( !frontier.isEmpty() ) {
//get the node at the start of the list and remove it
//in the first iteration this will be the root node
Node node = frontier.pop();
//found a goal so we're done
if( node.isGoal ) {
goal = node ;
break; //this breaks the while loop
}
//didn't find a goal yet so add the children at the end
if( node.children != null ) {
frontier.addAll( node.children );
}
}
Doing it this way means you add the nodes of the next level (children) at the end and pop the nodes higher up the tree from the front until you've found what you're searching for. That means you should always have only one or two levels of your tree in the list, i.e. the current level as well as the immediate children of any already processed current level node.
As you also can see there's no need to keep a explored set since we're operating on a tree.
Additionally you might want to think about whether you really need to build that prev map during iteration since you might have to remove elements again and a map is not really suited to get the path from your goal node to the root. You might want to keep a link to the parent in each node instead and thus once you've found the goal node you'd just iterate up until you reach the root.
Related
Just a disclamer, I am doing this for a homework, it's mainly focused on effiency of data structures though.
For a binary search tree i need to implement the delete function, i already created the main traversal system and the only thing i am left doing is to swap the values of a root with the minimal value of it's right subtree, in the case of left and right children. The way i am doing that is through a find the minimal node function.
public int findMin (Tree r1){
int min = r1.key;
while (r1.l != null) {
min = root.l.num;
r1 = r1.l;
}
return min;
}
Great, i found the node i am supposed to delete, my question is, is there a way to also delete the minimal node, without having to traverse the whole tree up until that same node again? Maybe through the function again? Does this function also delete the node or is that not parsed through
This is a common problem of partitioning a linked list into two parts. The list with nodes smaller than x will come first and the list of nodes larger than x will come after.
My question is - why do i need to set after.next to null after creating my two separate linked lists? Without setting it to null, I enter an infinite loop when trying to print this list.
My debugger shows that before_head.next has a never-ending list of nodes attached to it...
public Node partition(Node head, int x){
Node before_head=new Node(0);
Node before=before_head;
Node after_head=new Node(0);
Node after=after_head;
while(head != null){
if(head.val < x){
before.next=head;
before=before.next;
else{
after.next=head;
after=after.next;
}
head=head.next;
}
after.next=null;
before.next=after_head;
return before_head.next;
}
why do i need to set after.next to null after creating my two separate linked lists?
The last node of a linked list doesn't have a next node. In a linked list representation such as yours, that takes the form of the last node's next reference being null.
You are rearranging the existing nodes of the list by changing their next references. At the end of that process, after is a reference to the last node, therefore its next reference needs to be null. If it was also the last node in the original order then all is well -- its next reference is already null. If after was not the last node in the original order, however, then after.next will refer to one of the other nodes until you set it null. And whatever other node that is, it comes before after in the new order, forming a loop.
Note also that
before.next=after_head;
appears to be wrong. after_head is the dummy head node of the second partition, so you do not want to include it in the new list. I think you want
before.next = after_head.next;
I have a problem that I am running into a few issues with, the question is as follows:
Given a pre-constructed Binary Search Tree and an array, determine if the array will produce the same Binary Search Tree.
Now, this question will have a pre-constructed BST for you, and then it will run through the following code:
boolean valid = true;
for (int i = 0;valid && i < arr.length; i ++) {
valid &= tree.checkPattern(arr[i]);
}
//These two methods below are in a different class. For every element in the array,
//the checkPattern method will be called, initially passing in the root of the BST
public void checkPattern(int key) {
recursiveFunction(root, key);
}
public boolean recursiveFunction(TreeNode current, int key){
// Recursive function
}
The goal is to write therecursiveFunction(root, arr[i]), and a hint is that the TreeNode class contains a visited boolean that you are to use to help with this algorithm.
I can't quite seem to figure out how to solve this... Given a key, are you supposed to check to see where it would go in the primary BST, and if the parent has already been visited, then return false?
One way would be to build a new BST from the array, then compare the two trees. Think about how that builds the tree one node at a time.
Now, with a visited flag in every node, we start with all the flags being false, then the logic is:
For each value in the array, look for the node for that value (the target node) in the tree:
If the target node is not found, then answer is no (tree and array have different values).
If the path to the target node steps on any node that has not been visited yet, then answer is no (wrong order).
(optional) If the target node has already been visited, throw IllegalArgumentException (duplicate values in array not allowed).
Mark the target node visited.
Scan the tree (BFS or DFS, doesn't matter), and if you find any unvisited node, then answer is no (tree and array have different values).
If you get here, answer is yes.
Can we put the nodes of the BST inside either a HashMap or HashSet? If so how do we traverse the BST.This doubt arose while I was solving the TWO SUM BST.
You may put the nodes of a BinarySearchTree into a HashSet, or a HashMap (not sure what the Key,Value pairing would be for the Map). For the HashSet, I would simply traverse the BST in order. To solve the problem that you were given, I would tackle the problem like so:
// Returns true if the BST contains two nodes with elements that
// sum to k, otherwise false
public bool findTarget(TreeNode root, int k){
if(root == null){
throw new NullPointerException();
}
HashSet<Integer> set = new HashSet<Integer>();
return traverse(root, k, set);
}
// Traverses across the BST, in order, adding elements to the set
bool traverse(Node<T> node, int k, HashSet<Node<T>> set){
// If the node has a left child, traverse it first
if(node.left != null){
return traverse(node.left, k, set);
}
// Check to see if the set contains the element that would sum
// with the node we're checking's element to equal k
if(set.contains(k-node.element)){
return true;
}
// Add node's element to the set
set.add(node.element);
// If the node has a right child, traverse it after
if(node.right != null){
return traverse(node.right, k, set);
}
else{
// No two node's with elements summing k exist in the BST,
// since you reached the end and found nothing
return false;
}
}
Yes, you can. A Binary Search Tree has data like any other, and that data can be stored into any other type of collection in Java. Before I tell you how to traverse the BST, let me explain what it is in case you don't know.
A Binary Search Tree is a way of organizing data. The top node is usually called the root, and any data that is less than it will be put to the left of it, and any data that is greater than it will be put to the right of it. These are called the children of it, and the other node is called the parent. For instance, if your root was 2, 1 would be placed to the left of it, and 3 would be placed to the right. However, a node can only have at most 2 children, and the left and right branches can only differ by at most a length of 1. In the case where they differ by more than one, some swapping needs to be done.
To traverse the tree, you must first start at the left branch. With each level you go down, you must first check if the node has a left child. If it does, then go down one level. Keep going down until there are no more left children. This means this is the lowest value. Go up one level, take that as your next value. If it has a right child, take that one next. Continue this until you get to the root. Next, take the root. Finally, traverse the right branch with the same logic. Go to the first right child, and only take if it has no left child. If it does, take the farthest left child. Then take the parent(s). Continue this until you get to the farthest right child, which will be your highest value.
I have a graph which is essentially an ArrayList of Nodes, each of which stores their neighbors.
public class Node {
ArrayList<Node> neighbors;
String data;
public Node() {
data = null;
neighbors = new ArrayList<Node>();
}
}
I print out every path in this graph, but only do it n-levels deep. How should I go about coding this?
Or, if I should store this differently, feel free to let me know. But more importantly I want to know how to print out every path n-levels deep.
Just do a depth-limited traversal of the graph. This is just like depth-first search, except in the recursive step, you also add a variable called depth which is incremented every time you go down a depth. Then simply stop recursing once you've hit the desired depth.
Add an extra variable called visited in every node.
Do a breadth first search using a Queue and use the visited to prevent from forming a loop.
Do it for length n.