Graph depth first search sometimes works, sometimes doesn't - java

So I wrote a Graph class and I can't seem to do a depth first search on it properly depending on the sequencing of nodes. Here's what I mean:
If my graph looks like this:
A-B-D
|/
C
The DFS returns: "ABC"
But when it looks like this:
A-B
| |
D C
|
E
It will print ABCDE correctly.
The problem I've found lies in my getUnvisitedAdjacentNode() function. Here is the function:
public int getUnvisitedAdjacentNode(int n) {
for (int i = 0; i < this.nodeList.size(); i++) {
if (this.edges[n][i] == 1 && this.nodeList.get(i).wasVisited == false) {
return i;
}
}
return -1;
}
The problem, I've found is because it goes in "order" (just a for loop) , it will never get traverse D in the first situation because B gets visited and after C gets visited, B simply get's popped off of the stack. Maybe this isn't the problem.
Here's the code for my actual DFS traversal.
public void depthFirstTraverse() {
Stack<Node> stack = new Stack<Node>();
nodeList.get(0).wasVisited = true;
System.out.println(nodeList.get(0).item);
stack.push(nodeList.get(0));
while (!stack.isEmpty()) {
int nextNode = this.getUnvisitedAdjacentNode(stack.peek().index);
if (nextNode == -1) {
stack.pop();
} else {
nodeList.get(nextNode).wasVisited = true;
System.out.println(nodeList.get(nextNode).item);
stack.push(nodeList.get(nextNode));
}
}
for (int i = 0; i < nodeList.size(); i++) {
nodeList.get(i).wasVisited = false;
}
}

Fortunately I found my own mistake, the code above is all correct, except it was in the code that I hadn't pasted.
In case anybody cares, the problem lied in the fact that I completely disregarded the fact that ArrayLists have an "IndexOf()" method (stupid, I know) and decided to hack my own "index" field into my Node class. When dealing with my own indices, I had a minor bug which screwed up the traversal.
So the old line in my DFS algorithm looks like this:
int nextNode = this.getUnvisitedAdjacentNode(stack.peek().index);
But it should be:
int nextNode = this.getUnvisitedAdjacentNode(this.nodeList.indexOf(stack.peek()));

You said it. If you pop a node off of the stack, you need to make sure that all of its unvisited neighbors are on the stack first. Otherwise, there's no guarantee that everyone will be visited.
For example, in the first diagram you gave, if node A is visited first, and then node B, either node C or D will be visited next. However, if you only push one of them onto the stack, and then remove B, there will be no way of reaching the last one.
So what you may want to do it write a function getAllUnvisitedAdjacentNodes and push all of them onto the stack before you pop.

Related

Singly Linked List Reference Manipulation

I am Facing problems with Reference Manipulation:
First This is a Code Which takes a value x and traverses the List removing any Link with value Less than or Equal to X but it gives me a irregular output.Help is Appreciated.
public void rlx (int x){
Link p = head;//Initializing a pointer equal to head
for (Link c = head.next; c!=null;c=c.next) {//Initializing another Pointer with the Condition to termination
if((int)head.data<=x){//If the Value of head< = to X
head=head.next;//Skip the first and assign head to the second
}else if((int)c.data<=x){
p.next=c.next;//P.next skip c by pointing to c.next instead of c;
}
p=c; reinitialize p;
}
}
Main Method:
public static void main(String [] args){
LinkList l = new LinkList();
l.insertLast(1);
l.insertLast(2);
l.insertLast(3);
l.insertLast(4);
l.insertLast(3);
l.insertLast(2);
l.insertLast(1);
l.rlx(3);
System.out.print(l);
}
OutPut: [ 4, 2 ]
Your algorithm has a lot of issues, I'm really not sure where to start. First, you shouldn't be checking the head on each loop iteration, you should only be checking if c.data <= x. Second, you don't remove a node from a single linked list by simply pointing the previous pointer to the node that follows it. You should only be setting p = c if c.data > x not on every iteration. I generally have a rule against doing people's homework, but here
public void rlx (int x){
While(head != null && (int)head.data <= x) {
head = head.next
}
Link p = head;//Initializing a pointer equal to head
for (Link c = head.next; c!=null;c=c.next) {//Initializing another Pointer with the Condition to termination
if((int)c.data<=x){
p.next=c.next;//P.next skip c by pointing to c.next instead of c;
}
Else {
p=c;
}
}
}
I haven't bothered to test that because it's basically pseudo code, and I'm assuming your Link type is a pointer object. Basically, you need to do garbage collection explicitly, but more importantly you should be removing the head until you find a value that is larger than x in a while loop, then using a separate for loop to remove values after the head. Otherwise, if the head is smaller than x and c is smaller than x you'll remove the head, which will then become c, but since p is still the old head you'll update your list so that the old head points to the next value which is meaningless because nothing points to p and your current head would be c which isn't greater than x either. Then, p would then become c, which isn't greater than x. p should only ever point to the most recent Link found to be greater than x, and only replaced after you find a Link with value greater than x.

Java depth-first recursive function

Im writing a recursive function in Java (graph theory) to get all paths in a 4x4 table, beginning at a random starting point. Possible directions are horizontal, vertical & diagonal, but I have a requirement that the same location cannot be visited twice.
The script works fine so far, I get a lot of combinations. The problem is that in the for loop of the function, when there is more than one possible way, then I get wrong results in the second and following loops because the boolean[] tempvisited is not getting back to his old values.
I hope there is someone, that may understand my English and my problem too. Here is my code so far:
// here I define a constant input of values:
String letters = "1548987425461854"
// This matrix shows all possible directions from every startpoint in the matrix:
// from the second value, you may get to the following locations: 1,3,5,6 and 7
private int[][] matrix = {
{1,4,5},
{0,2,4,5,6},
{1,3,5,6,7},
{2,6,7},
{0,1,5,8,9},
{0,1,2,4,6,8,9,10},
{1,2,3,5,7,9,10,11},
{2,3,6,10,11},
{4,5,9,12,13},
{4,5,6,8,10,12,13,14},
{5,6,7,9,11,13,14,15},
{6,7,10,14,15},
{8,9,13},
{8,9,10,12,14},
{9,10,11,13,15},
{10,11,14}
};
// Here begins the recursive function
public List<Combination> depthFirst(int vertex, boolean[] visited, Combination zeichen, List<Combination> combis){
// A temporary list of booleans to mark every value position visited or not
boolean[] tempvisited = new boolean[16];
// combis is the whole list of ways, zeichen is just the actual combination
zeichen.name = zeichen.name + this.letters.charAt(vertex);
combis.add(zeichen.name);
//marks actual value as visited
visited[vertex] = true;
for(int i = 0; i < 16; i++){
tempvisited[i] = visited[i];
}//end for
// going to next possible locations
for (int i = 0; i < this.matrix[vertex].length; i++) {
if (!visited[this.matrix[vertex][i]]) {
combis = depthFirst(this.matrix[vertex][i], tempvisited, zeichen, combis);
}//end if
}//end for
return combis;
}
You have the right idea with tempvisited, making a copy. But you're doing so in the wrong place.
You're setting visited[vertex] = true, which means that the visited you passed in is changing. What you want is for visited to never change. Make a copy of it, and make your changes to that copy.
Also, I notice that you use the same zeichen every time. So if you have a path 3 steps long, your combis list with be 3 copies of the same zeichen. That seems incorrect.
You set visited[vertex] to true before the first for loop; you could reset it to false just before you return. If every call undoes the change it did (directly), then every call will return with visited back to its state when that call was made. No tempvisited needed.
Take a look to this other recursive solution (pseudocode) for the Depth First Search (DFS).
void search(Node root) {
if (root == null) return;
visit(root);
root.visited = true;
foreach (Node n in root.adjacent) {
if (n.visited == false)
search(n);
}
}
Actually you don't need a copy of the visited array. Mark the node as visited right before the reccurrent call of depthFirst and then "unmark" it right after the call. Something like:
for (int i = 0; i < this.matrix[vertex].length; i++) {
if (!visited[this.matrix[vertex][i]]) {
visited[this.matrix[vertex][i]] = true;
combis = depthFirst(this.matrix[vertex][i], tempvisited, zeichen, combis);
visited[this.matrix[vertex][i]] = false;
}//end if
}//end for

Constructing a Binary Tree from its traversals

I'm trying to construct a binary tree (unbalanced), given its traversals. I'm currently doing preorder + inorder but when I figure this out postorder will be no issue at all.
I realize there are some question on the topic already but none of them seemed to answer my question. I've got a recursive method that takes the Preorder and the Inorder of a binary tree to reconstruct it, but is for some reason failing to link the root node with the subsequent children.
Note: I don't want a solution. I've been trying to figure this out for a few hours now and even jotted down the recursion on paper and everything seems fine... so I must be missing something subtle. Here's the code:
public static <T> BinaryNode<T> prePlusIn( T[] pre, T[] in)
{
if(pre.length != in.length)
throw new IllegalArgumentException();
BinaryNode<T> base = new BinaryNode();
base.element = pre[0]; // * Get root from the preorder traversal.
int indexOfRoot = -1 ;
if(pre.length == 0 && in.length == 0)
return null;
if(pre.length == 1 && in.length == 1 && pre[0].equals(in[0]))
return base; // * If both arrays are of size 1, element is a leaf.
for(int i = 0; i < in.length -1; i++){
if(in[i].equals(pre[0])){ // * Get the index of the root
indexOfRoot = i; // in the inorder traversal.
break;
}
} // * If we cannot, the tree cannot be constructed as the traversals differ.
if (indexOfRoot == -1) throw new IllegalArgumentException();
// * Now, we recursively set the left and right subtrees of
// the above "base" root node to whatever the new preorder
// and inorder traversals end up constructing.
T[] preleft = Arrays.copyOfRange(pre, 1, indexOfRoot + 1);
T[] preright = Arrays.copyOfRange(pre, indexOfRoot + 1, pre.length);
T[] inleft = Arrays.copyOfRange(in, 0, indexOfRoot);
T[] inright = Arrays.copyOfRange(in, indexOfRoot + 1, in.length);
base.left = prePlusIn( preleft, inleft); // * Construct left subtree.
base.right = prePlusIn( preright, inright); // * Construc right subtree.
return base; // * Return fully constructed tree
}
Basically, I construct additional arrays that house the pre- and inorder traversals of the left and right subtree (this seems terribly inefficient but I could not think of a better way with no helpers methods).
Any ideas would be quite appreciated.
Side note: While debugging it seems that the root note never receives the connections to the additional nodes (they remain null). From what I can see though, that should not happen...
EDIT: To clarify, the method is throwing the IllegalArgumentException # line 21 (else branch of the for loop, which should only be thrown if the traversals contain different elements.
EDIT2: Figured this out thanks to a helpful post from #Philip (coincidentally, we have the same first name... fun!). However, if anyone happens to have any advice on improving efficiency, I would appreciate the input.
this code is very suspicious to me
for(int i = 0; i < in.length -1; i++){
if(in[i].equals(base.element)){ // * Get the index of the root
indexOfRoot = i; // in the inorder traversal.
break;
} // * If we cannot, the tree cannot be constructed as the traversals differ.
else throw new IllegalArgumentException();
}
You enter the loop and i is set to 0, if i is less than in.length - 1 you evaluate the body of the loop which is an if expresion. At this point one of two things will happen
in[i] equals base.element in which case indexOfRoot will be set to 0 and you will break out of the loop
You throw an exception
Either way you never actually increment i
Try to rework this loop to do what you want, since it definitely isn't doing what you want now. You might try something like
int indexOfRoot = -1; //an impossible value
for(int i = 0; i < in.length -1; i++){
if(in[i].equals(base.element)){ // * Get the index of the root
indexOfRoot = i; // in the inorder traversal.
break;
}
}
if(indexOfRoot == -1){//if the root was never set
throw new IllegalArgumentException();
}
although that is still kinda ugly (for one thing, base.element never changes, so you might want to use pre[0] for clarity). And, by no means am I sure it is fully correct. Still, it is probably closer to what you want

Calculating longest path

I have a n-ary tree which contains key values (integers) in each node. I would like to calculate the minimum depth of the tree. Here is what I have come up with so far:
int min = 0;
private int getMinDepth(Node node, int counter, int temp){
if(node == null){
//if it is the first branch record min
//otherwise compare min to this value
//and record the minimum value
if(counter == 0){
temp = min;
}else{
temp = Math.min(temp, min);
min = 0;
}
counter++;//counter should increment by 1 when at end of branch
return temp;
}
min++;
getMinDepth(node.q1, counter, min);
getMinDepth(node.q2, counter, min);
getMinDepth(node.q3, counter, min);
getMinDepth(node.q4, counter, min);
return temp;
}
The code is called like so:
int minDepth = getMinDepth(root, 0, 0);
The idea is that if the tree is traversing down the first branch (branch number is tracked by counter), then we set the temp holder to store this branch depth. From then on, compare the next branch length and if it smaller, then make temp = that length. For some reason counter is not incrementing at all and always staying at zero. Anyone know what I am doing wrong?
I think you're better off doing a breadth-first search. Your current implementation tries to be depth-first, which means it could end up exploring the whole tree if the branches happen to be in an awkward order.
To do a breadth-first search, you need a queue (a ArrayDeque is probably the right choice). You'll then need a little class that holds a node and a depth. The algorithm goes a little something like this:
Queue<NodeWithDepth> q = new ArrayDeque<NodeWithDepth>();
q.add(new NodeWithDepth(root, 1));
while (true) {
NodeWithDepth nwd = q.remove();
if (hasNoChildren(nwd.node())) return nwd.depth();
if (nwd.node().q1 != null) q.add(new NodeWithDepth(nwd.node().q1, nwd.depth() + 1));
if (nwd.node().q2 != null) q.add(new NodeWithDepth(nwd.node().q2, nwd.depth() + 1));
if (nwd.node().q3 != null) q.add(new NodeWithDepth(nwd.node().q3, nwd.depth() + 1));
if (nwd.node().q4 != null) q.add(new NodeWithDepth(nwd.node().q4, nwd.depth() + 1));
}
This looks like it uses more memory than a depth-first search, but when you consider that stack frames consume memory, and that this will explore less of the tree than a depth-first search, you'll see that's not the case. Probably.
Anyway, see how you get on with it.
You are passing the counter variable by value, not by reference. Thus, any changes made to it are local to the current stack frame and are lost as soon as the function returns and that frame is popped of the stack. Java doesn't support passing primitives (or anything really) by reference, so you'd either have to pass it as a single element array or wrap it in an object to get the behavior you're looking for.
Here's a simpler (untested) version that avoids the need to pass a variable by reference:
private int getMinDepth(QuadTreeNode node){
if(node == null)
return 0;
return 1 + Math.min(
Math.min(getMinDepth(node.q1), getMinDepth(node.q2)),
Math.min(getMinDepth(node.q3), getMinDepth(node.q4)));
}
Both your version and the one above are inefficient because they search the entire tree, when really you only need to search down to the shallowest depth. To do it efficiently, use a queue to do a breadth-first search like Tom recommended. Note however, that the trade-off required to get this extra speed is the extra memory used by the queue.
Edit:
I decided to go ahead and write a breadth first search version that doesn't assume you have a class that keeps track of the nodes' depths (like Tom's NodeWithDepth). Once again, I haven't tested it or even compiled it... But I think it should be enough to get you going even if it doesn't work right out of the box. This version should perform faster on large, complex trees, but also uses more memory to store the queue.
private int getMinDepth(QuadTreeNode node){
// Handle the empty tree case
if(node == null)
return 0;
// Perform a breadth first search for the shallowest null child
// while keeping track of how deep into the tree we are.
LinkedList<QuadTreeNode> queue = new LinkedList<QuadTreeNode>();
queue.addLast(node);
int currentCountTilNextDepth = 1;
int nextCountTilNextDepth = 0;
int depth = 1;
while(!queue.isEmpty()){
// Check if we're transitioning to the next depth
if(currentCountTilNextDepth <= 0){
currentCountTilNextDepth = nextCountTilNextDepth;
nextCountTilNextDepth = 0;
depth++;
}
// If this node has a null child, we're done
QuadTreeNode node = queue.removeFirst();
if(node.q1 == null || node.q2 == null || node.q3 == null || node.q4 == null)
break;
// If it didn't have a null child, add all the children to the queue
queue.addLast(node.q1);
queue.addLast(node.q2);
queue.addLast(node.q3);
queue.addLast(node.q4);
// Housekeeping to keep track of when we need to increment our depth
nextCountTilNextDepth += 4;
currentCountTilNextDepth--;
}
// Return the depth of the shallowest node that had a null child
return depth;
}
Counter is always staying at zero because primitives in java are called by value. This means if you overwrite the value in a function call the caller won't see the change. Or if you're familiar with C++ notation it's foo(int x) instead of foo(int& x).
One solution would be to use an Integer object since objects are call-by-reference.
Since you're interested in the minimum depth a breadth first solution will work just fine, but you may get memory problems for large trees.
If you assume that the tree may become rather large an IDS solution would be the best. This way you'll get the time complexity of the breadth first variant with the space complexity of a depth first solution.
Here's a small example since IDS isn't as well known as its brethren (though much more useful for serious stuff!). I assume that every node has a list with children for simplicity (and since it's more general).
public static<T> int getMinDepth(Node<T> root) {
int depth = 0;
while (!getMinDepth(root, depth)) depth++;
return depth;
}
private static<T> boolean getMinDepth(Node<T> node, int depth) {
if (depth == 0)
return node.children.isEmpty();
for (Node<T> child : node.children)
if (getMinDepth(child, depth - 1)) return true;
return false;
}
For a short explanation see http://en.wikipedia.org/wiki/Iterative_deepening_depth-first_search

how to go the middle of the singularly linked list in one iteration?

Recently I have been asked one question that in a singularly linked list how do we go to the middle of the list in one iteration.
A --> B --> C --> D (even nodes)
for this it should return address which points to B
A --> B --> C (odd nodes)
for this also it should return address which points to B
There is one solution of taking two pointers one moves one time and other moves two times but it does not seem working here
LinkedList p1,p2;
while(p2.next != null)
{
p1 = p1.next;
p2 = p2.next.next;
}
System.out.print("middle of the node" + p1.data); //This does not give accurate result in odd and even
Please help if anyone has did this before.
The basic algorithm would be
0 Take two pointers
1 Make both pointing to first node
2 Increment first with two node and first if its successful then traverse second to one node ahead
3 when second reaches end first one would be at middle.
Update:
It will definitely work in odd case, for even case you need to check one more condition if first point is allowed to move next but not next to next then both pointers will be at middle you need to decide which to take as middle
You can't advance p1 unless you successfully advanced p2 twice; otherwise, with a list length of 2 you end up with both pointing at the end (and you indicated even length lists should round toward the beginning).
So:
while ( p2.next != null ) {
p2 = p2.next;
if (p2.next != null) {
p2 = p2.next;
p1 = p1.next;
}
}
I know you've already accepted an answer, but this whole question sounds like an exercise in cleverness rather than an attempt to get the correct solution. Why would you do something in O(n) when you can do it in O(n/2)?
EDIT: This used to assert O(1) performance, and that is simply not correct. Thanks to ysth for pointing that out.
In practice, you would do this in zero iterations:
LinkedList list = ...
int size = list.size();
int middle = (size / 2) + (size % 2 == 0 ? 0 : 1) - 1; //index of middle item
Object o = list.get(middle); //or ListIterator it = list.listIterator(middle);
The solution of taking two pointers and one moves a half the rate should work fine. Most likely it is not the solution but your actual implementation that is the problem. Post more details of your implementation.
static ListElement findMiddle(ListElement head){
ListElement slower = head;
ListElement faster = head;
while(faster.next != null && faster.next.next !=null ){
faster = faster.next.next;
slower = slower.next;
}
return slower;
}
public static Node middle(Node head){
Node slow=head,fast=head;
while(fast!=null& fast.next!=null && fast.next.next!=null){
slow=slow.next;
fast=fast.next.next;
}
if(fast!=null && fast.next!=null){
slow=slow.next;
}
return slow;
}
public ListNode middleNode(ListNode head) {
if(head == null) return head;
ListNode slow = head;
ListNode fast = head;
while(fast != null && fast.next != null) {
fast = fast.next.next;
slow = slow.next;
}
return slow;
}

Categories