DFS method not working properly - java

I expect the DFS method to print the path as 1->2->4->5 but it shows 1->2->3->4->5 can you please hint how the method can be fixed with the least amount of code addendum?
/**
* Created by mona on 5/28/16.
*/
import java.util.Stack;
public class DepthFirstSearch {
public static void DFS(GraphNode root, int num) {
if (root.val == num) {
System.out.println("root has the value "+num);
}
System.out.println(" current value is "+root.val);
Stack<GraphNode> stack = new Stack<>();
stack.push(root);
while (!stack.isEmpty()) {
for (GraphNode g : stack.pop().neighbors) {
if (!g.visited) {
System.out.println(" current value is "+g.val);
if (g.val == num) {
System.out.println("Found");
}
g.visited = true;
stack.push(g);
}
}
}
}
public static void main(String[] args) {
GraphNode n1 = new GraphNode(1);
GraphNode n2 = new GraphNode(2);
GraphNode n3 = new GraphNode(3);
GraphNode n4 = new GraphNode(4);
GraphNode n5 = new GraphNode(5);
n1.neighbors = new GraphNode[] {n2};
n2.neighbors = new GraphNode[] {n4,n3};
n3.neighbors = new GraphNode[] {n4};
n4.neighbors = new GraphNode[] {n5};
n5.neighbors = new GraphNode[] {};
DFS(n1, 5);
}
}
Here's the code for GraphNode class:
/**
* Created by mona on 5/27/16.
*/
public class GraphNode {
int val;
GraphNode next;
GraphNode[] neighbors;
boolean visited;
GraphNode(int val) {
this.val = val;
this.visited = false;
}
GraphNode(int val, GraphNode[] neighbors) {
this.val = val;
this.neighbors = neighbors;
this.visited = false;
}
public String toString() {
return "value is: "+this.val;
}
}

To get a path to the node, it's insufficient to just add all the nodes that you encounter, since you could run into a "dead end" in the graph or add nodes not actually on the path. To prevent this you need to keep track of the nodes that contained a node as neighbor when you inserted them to the stack:
Map<GraphNode, GraphNode> parents = new HashMap<>();
outer: while (!stack.isEmpty()) {
GraphNode currentElement = stack.pop();
for (GraphNode g : currentElement.neighbors) {
if (!g.visited) {
parents.put(g, currentElement);
System.out.println(" current value is "+g.val);
if (g.val == num) {
System.out.println("Found");
List<GraphNode> path = reconstructPath(parents, g);
// use path, e.g.
System.out.println(path.stream().map(n -> Integer.toString(n.val)).collect(Collectors.joining("->")));
break outer;
}
g.visited = true;
stack.push(g);
}
}
}
static List<GraphNode> reconstructPath(Map<GraphNode, GraphNode> parents, GraphNode end) {
List<GraphNode> list = new ArrayList<>();
while (end != null) {
list.add(end);
end = parents.get(end);
}
Collections.reverse(list);
return list;
}

Related

How to reverse a Linked List?

I am working on a project for my Data Structures class that asks me to write a class to implement a linked list of ints.
Use an inner class for the Node.
Include the methods below.
Write a tester to enable you to test all of the methods with whatever data you want in any order.
I have to create a method called "public LinkedListOfInts reverse()". This method is meant to "Return a copy of your Linked List but in reverse order." I have my code for this method down below. However, when I try to reverse a list it only prints the head. For Example, if I have a list like "[16, 1, 8, 7, 10, 10, 14, 17, 11, 4,] and I try to reverse it my output is [ 16, ]. Does someone know how correct my code so I can reverse a linked list?
import java.util.Random;
import java.util.Scanner;
public class LinkedListOfInts {
Node head;
Node tail;
private class Node {
int value;
Node nextNode;
public Node(int value, Node nextNode) {
this.value = value;
this.nextNode = nextNode;
}
}
public LinkedListOfInts(LinkedListOfInts other) {
Node tail = null;
for (Node n = other.head; n != null; n = n.nextNode) {
if (tail == null)
this.head = tail = new Node(n.value, null);
else {
tail.nextNode = new Node(n.value, null);
tail = tail.nextNode;
}
}
}
public LinkedListOfInts(int[] other) {
Node[] nodes = new Node[other.length];
for (int index = 0; index < other.length; index++) {
nodes[index] = new Node(other[index], null);
if (index > 0) {
nodes[index - 1].nextNode = nodes[index];
}
}
head = nodes[0];
}
public LinkedListOfInts(int N, int low, int high) {
Random random = new Random();
for (int i = 0; i < N; i++)
this.addToFront(random.nextInt(high - low) + low);
}
public void addToFront(int x) {
head = new Node(x, head);
}
public LinkedListOfInts reverse() {
if (head == null)
return null;
Node current = head;
Node previous = null;
Node nextNode = null;
while (current != null) {
nextNode = current.nextNode;
current.nextNode = previous;
previous = current;
current = nextNode;
}
return this;
}
public String toString() {
String result = " ";
for (Node ptr = head; ptr != null; ptr = ptr.nextNode)
result += ptr.value + " ";
return result;
}
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
LinkedListOfInts list = new LinkedListOfInts(10, 1, 20);
LinkedListOfInts copy = new LinkedListOfInts(list);
boolean done = false;
while (!done) {
System.out.println("1. Reverse");
System.out.println("2. toString");
switch (input.nextInt()) {
case 11:
System.out.println("Reverse the List");
System.out.println(copy.reverse());
break;
case 12:
System.out.println("toString");
System.out.println(list.toString());
break;
}
}
}
}
Here is a working example for reversing your LinkedList. Keep in mind that you are not copying the content of the LinkedList. So if you reverse the list, the original list's head is now the tail and returns only one int.
import java.util.Random;
import java.util.Scanner;
public class LinkedListOfInts{
Node head;
Node tail;
private class Node {
int value;
Node nextNode;
public Node(int value, Node nextNode) {
this.value = value;
this.nextNode = nextNode;
}
#Override
public String toString() {
return "Node{" +
"value=" + value +
", nextNode=" + nextNode +
'}';
}
}
public LinkedListOfInts(LinkedListOfInts other) {
System.out.println(other.tail);
head = other.head;
tail = other.tail;
System.out.println(this);
}
public LinkedListOfInts(int N, int low, int high) {
Random random = new Random();
for (int i = 0; i < N; i++) {
this.addToFront(random.nextInt(high - low) + low);
}
Node node=head;
while(node.nextNode!=null){
node = node.nextNode;
}
tail = node;
}
public void addToFront(int x) {
head = new Node(x, head);
}
public LinkedListOfInts reverse() {
Node previous = null;
Node curr = head;
Node nex;
while (curr != null)
{
nex = curr.nextNode;
curr.nextNode = previous;
previous = curr;
curr = nex;
}
head = previous;
return this;
}
public String toString() {
StringBuilder result = new StringBuilder(" ");
for (Node ptr = head; ptr != null; ptr = ptr.nextNode)
result.append(ptr.value).append(" ");
return result.toString();
}
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
LinkedListOfInts list = new LinkedListOfInts(10, 1, 20);
LinkedListOfInts copy = new LinkedListOfInts(list);
boolean done = false;
while (!done) {
System.out.println("1. Reverse");
System.out.println("2. toString");
switch (input.nextInt()) {
case 1:
System.out.println("Reverse the List");
System.out.println(copy.reverse());
break;
case 2:
System.out.println("toString");
System.out.println(list);
break;
}
}
}
}

How to break random elements in doubly linkedList

hello i am trying to generate a random doubly linkedlist but i have to insert the node with a negative value and its next node(value doesnt matter) to the HEAD of the list but when i compile the program i am stuck in an infinite loop with one repeating number.I think i connected the list wrong but i am not sure. For context LC is the NODE class, tete is head queue is tail, prev and suiv and next and previous pointer.
class LC {
public int data;
public LC suiv;
public LC prec;
}
public class ChainesDouble {
public static void main(String[] args) {
// TODO Auto-generated method stub
//Détermine an even number N between 10 and 30
int N = (int)(Math.random()*16)+5;
N = (N*2);
System.out.println("La valeur de N = " + N);
// Create a doubly linkedlist with N elements
LC tete = null;
LC queue = null;
for (int i = 0; i < N/2; i++) {
int valeur = getRandom();
int next = getRandom();
//If the generated number is negative insert that number and
//next value into the head of the list
if(valeur <0) {
LC temp = new LC();
temp.data = valeur;
if(tete == null) {
queue = temp;
}
temp = new LC();
temp.data = next ;
tete.prec = temp ;
temp.suiv = tete ;
tete = temp ;
tete.prec = temp ;
temp.suiv = tete ;
tete = temp ;
//If the number is positive, insert the element and the
//next element into the TAIL of the list
}
else {
LC temp = new LC();
temp.data = valeur;
if(queue == null) {
tete = temp;
queue = temp;
}else {
temp.prec = queue;
queue.suiv = temp ;
queue = temp ;
}
temp.prec = queue;
queue.suiv = temp ;
queue = temp ;
}
}
public static int getRandom(){
int N = (int)(Math.random()*42);
if(N<21) {
N -=30;//Rand(-10;-30)
}
else {
N-=11;//Rand(10;30)
}
return N;
}
}
public static void main(String[] args) {
Random random = new Random();
int halfSize = random.nextInt(30) + 1;
ListNode head = createLinkedList(halfSize, random);
System.out.println(printToString(head));
}
private static String printToString(ListNode node) {
StringBuilder buf = new StringBuilder();
while (node != null) {
if (buf.length() > 0)
buf.append("->");
buf.append(node.value);
node = node.next;
}
return buf.toString();
}
public static ListNode createLinkedList(int halfSize, Random random) {
ListNode head = null;
ListNode tail = null;
for (int i = 0; i < halfSize; i++) {
int one = getRandomValue(random);
int two = getRandomValue(random);
if (one >= 0) {
tail = addTail(one, tail);
head = head == null ? tail : head;
tail = addTail(two, tail);
} else {
head = addHead(one, head);
head = addHead(two, head);
}
}
return head;
}
private static ListNode addHead(int value, ListNode head) {
ListNode node = new ListNode(value);
node.next = head;
if (head != null)
head.prev = node;
return node;
}
private static ListNode addTail(int value, ListNode tail) {
ListNode node = new ListNode(value);
node.prev = tail;
if (tail != null)
tail.next = node;
return node;
}
private static int getRandomValue(Random random) {
return (random.nextInt(30) + 1) * (random.nextBoolean() ? 1 : -1);
}
public static final class ListNode {
public final int value;
public ListNode next;
public ListNode prev;
public ListNode(int value) {
this.value = value;
}
#Override
public String toString() {
return String.valueOf(value);
}
}
I don't know if i got your requirements correctly. But here is a loop that would achieve a doubly linked list with your tete and queue. The comments explain the logic.
class LC {
public int data;
public LC suiv;
public LC prec;
}
public class ChainesDouble {
public static int getRandom(){
int N = (int)(Math.random()*42);
if(N<21) {
N -=30;
} else {
N-=11;
}
return N;
}
public static void main(String[] args) {
int N = (int)(Math.random()*16)+5;
N = (N*2);
System.out.println("La valeur de N = " + N);
LC tete = null;
LC queue = null;
for (int i = 0; i < N/2; i++) {
int valeur = getRandom();
int next = getRandom();
//get the two random values
LC temp_a = new LC();
LC temp_b = new LC();
//Store the data in the two nodes
temp_a.data = valeur;
temp_b.data = next ;
//link the two nodes
temp_a.suiv = temp_b;
temp_b.prec = temp_a;
//If the list is empty, then initialize tete(head) and queue(tail)
if(tete == null) {
tete = temp_a;
queue = temp_b;
} else {
if(valeur <0) { //If valeur is negative, add to tete
temp_b.suiv = tete;
tete.prec = temp_b;
tete = temp_a;
}
else { //If valeur is positive, add to queue
queue.suiv = temp_a;
temp_a.prec = queue;
queue = temp_b;
}
}
}
//Test Program
LC temp = tete;
while (temp!=null) {
System.out.println(temp.data);
temp=temp.suiv;
}
//Search for second multiple of 5
LC search = tete;
int count = 0;
boolean found = false;
while (search!=null) {
if (search.data%5==0)
count++;
if (count==2) {
found = true;
System.out.println("Found "+search.data);
break;
}
search = search.suiv;
}
//if found
if (found) {
int position = 5;
if (search.data%10==0) position = 10;
System.out.println("Position "+position);
//remove search for current position
if (search.suiv!=null) {
LC prev = search.prec;
LC next = search.suiv;
prev.suiv = next;
next.prec = prev;
} else {
search.prec.suiv = null;
}
//move pointer to desired position
LC move = tete;
int cur = 1;
while(move!=null) {
move = move.suiv;
cur++;
if (cur==(position - 1)) {
break;
}
}
System.out.println("shifting "+search.data+" to after "+move.data);
//link searched item into desired position
search.suiv = move.suiv;
move.suiv.prec = search;
move.suiv = search;
search.prec = move;
}
}
}

Adding two numbers given (digits in Linked List) using Strings

I am trying to add two non negative numbers, the digits of which are stored in reverse order in two separate linked lists. The answer should also be a linked list with digits reversed and no trailing zeros.
I understand that there is a way to solve this question by adding digits and maintaining a carry each time, but I am trying to solve it by using addition operation on numbers.
Here's my code:
/**
* Definition for singly-linked list.
* class ListNode {
* public int val;
* public ListNode next;
* ListNode(int x) { val = x; next = null; }
* }
*/
public class Solution {
public ListNode addTwoNumbers(ListNode a, ListNode b) {
if(a==null || b==null){
return null;
}
String num1 = "";
String num2 = "";
ListNode temp1 = a;
ListNode temp2 = b;
while(temp1!=null){
num1 = num1+Integer.toString(temp1.val);
temp1 = temp1.next;
}
new StringBuilder(num1).reverse().toString();
double value1 = Double.parseDouble(num1);
while(temp2!=null){
num2 = num2+Integer.toString(temp2.val);
temp2 = temp2.next;
}
new StringBuilder(num2).reverse().toString();
double value2 = Double.parseDouble(num2);
double result = value1+value2;
String res = String.format("%.0f",result);
ListNode first_node = new ListNode(Character.getNumericValue(res.charAt(0)));
ListNode ans = first_node;
for(int j=1;j<res.length();j++){
ListNode node = new ListNode(Character.getNumericValue(res.charAt(j)));
add(node,ans);
}
return ans;
}
public void add(ListNode node, ListNode ans){
ListNode temp;
temp = ans;
ans = node;
ans.next = temp;
}
}
My code has been giving wrong answers. Can anyone point out the errors?
Your approach is not correct and indirect.
You are trying to do big numbers arithmetics using floating point operations.
As a result - computing errors.
We have:
List<Integer> firstNumber;
List<Integer> secondNumber;
Lets assume firstNumber > secondNumber.
Try this alogrithm:
List<Integer> result = new ArrayList<>();
int i = 0;
int appendix = 0;
for (; i < secondNumber.size(); i++) {
int sum = firstNumber.get(i) + secondNumber.get(i) + appendix;
result.append(sum % 10);
appendix = sum / 10;
}
for (; i < firstNumber.size(); i++) {
int sum = firstNumber.get(i) + appendix;
result.append(sum % 10);
appendix = sum / 10;
}
if (appendix != 0)
result.append(appendix);
return result;
Your add function looks incorrect. You will get you number in the reverse order than what is expected.
Also, your solution is missing the point of the question. Your approach will fail if you have a number with a lot of digits (even double has its limits ~ 2^1024 I think). A linked list representation allows for numbers even bigger.
The correct solution would just iterate through both the lists simultaneously with a carry digit while creating the solution list. If this is a question in an assignment or coding competition, your solution would be judged wrong.
Your add method is wrong, it doesn't build correctly the list. Here is how the final part of your method should look, without the add method:
for(int j=1;j<res.length();j++){
ans.next = new ListNode(Character.getNumericValue(res.charAt(j)));;
ans = ans.next;
}
return first_node;
In your approach, the variable ans is not updating. You can try this:
ans = add(node,ans);
and in your add method, change the method to return ListNode ans
Your approach is not straightforward and wouldn't give you expected results.
Here is a simple approach which wouldn't require much explanation as the addition is simple integer by integer.
Do note that i carry forward when the sum of two integers is greater than 9 else continue with the sum of next integers from both the list.
class Node {
private Object data;
private Node next;
public Object getData() { return data; }
public void setData(Object data) { this.data = data; }
public Node getNext() { return next; }
public void setNext(Node next) { this.next = next; }
public Node(final Object data, final Node next) {
this.data = data;
this.next = next;
}
#Override
public String toString() { return "Node:[Data=" + data + "]"; }
}
class SinglyLinkedList {
Node start;
public SinglyLinkedList() { start = null; }
public void addFront(final Object data) {
// create a reference to the start node with new data
Node node = new Node(data, start);
// assign our start to a new node
start = node;
}
public void addRear(final Object data) {
Node node = new Node(data, null);
Node current = start;
if (current != null) {
while (current.getNext() != null) {
current = current.getNext();
}
current.setNext(node);
} else {
addFront(data);
}
}
public void deleteNode(final Object data) {
Node previous = start;
if (previous == null) {
return;
}
Node current = previous.getNext();
if (previous != null && previous.getData().equals(data)) {
start = previous.getNext();
previous = current;
current = previous.getNext();
return;
}
while (current != null) {
if (current.getData().equals(data)) {
previous.setNext(current.getNext());
current = previous.getNext();
} else {
previous = previous.getNext();
current = previous.getNext();
}
}
}
public Object getFront() {
if (start != null) {
return start.getData();
} else {
return null;
}
}
public void print() {
Node current = start;
if (current == null) {
System.out.println("SingleLinkedList is Empty");
}
while (current != null) {
System.out.print(current);
current = current.getNext();
if (current != null) {
System.out.print(", ");
}
}
}
public int size() {
int size = 0;
Node current = start;
while (current != null) {
current = current.getNext();
size++;
}
return size;
}
public Node getStart() {
return this.start;
}
public Node getRear() {
Node current = start;
Node previous = current;
while (current != null) {
previous = current;
current = current.getNext();
}
return previous;
}
}
public class AddNumbersInSinglyLinkedList {
public static void main(String[] args) {
SinglyLinkedList listOne = new SinglyLinkedList();
SinglyLinkedList listTwo = new SinglyLinkedList();
listOne.addFront(5);
listOne.addFront(1);
listOne.addFront(3);
listOne.print();
System.out.println();
listTwo.addFront(2);
listTwo.addFront(9);
listTwo.addFront(5);
listTwo.print();
SinglyLinkedList listThree = add(listOne, listTwo);
System.out.println();
listThree.print();
}
private static SinglyLinkedList add(SinglyLinkedList listOne, SinglyLinkedList listTwo) {
SinglyLinkedList result = new SinglyLinkedList();
Node startOne = listOne.getStart();
Node startTwo = listTwo.getStart();
int carry = 0;
while (startOne != null || startTwo != null) {
int one = 0;
int two = 0;
if (startOne != null) {
one = (Integer) startOne.getData();
startOne = startOne.getNext();
}
if (startTwo != null) {
two = (Integer) startTwo.getData();
startTwo = startTwo.getNext();
}
int sum = carry + one + two;
carry = 0;
if (sum > 9) {
carry = sum / 10;
result.addRear(sum % 10);
} else {
result.addRear(sum);
}
}
return result;
}
}
Sample Run
Node:[Data=3], Node:[Data=1], Node:[Data=5]
Node:[Data=5], Node:[Data=9], Node:[Data=2]
Node:[Data=8], Node:[Data=0], Node:[Data=8]

Java Double LinkedList print

I have posted this code several times I apologize if you keep looking at this question. I've been working on this for a bit so any help would be helpful i've done as much as I can so far. But when my program prints the data it switches the 8 and the 7 around and I can't figure out why! Here is all the code. And I have not started making my remove method yet so disregard that functionality.
public class MyLinkedList<AnyType> implements Iterable<AnyType> {
private int theSize;
private Node<AnyType> beginMarker;
private Node<AnyType> endMarker;
public class Node<AnyType> {
public Node(AnyType data, Node<AnyType> head, Node<AnyType> tail) {
myData = data;
myHead = head;
myTail = tail;
}
public AnyType myData;
public Node<AnyType> myHead;
public Node<AnyType> myTail;
}
public MyLinkedList() {
beginMarker = new Node(null, endMarker, null);
endMarker = new Node(null, null, beginMarker);
theSize = 0;
}
public void clear() {
beginMarker.myHead = endMarker;
endMarker.myTail = beginMarker;
}
public int size() {
return theSize;
}
public boolean exist(AnyType newVal) {
beginMarker.myHead.myData = newVal;
if (newVal != null) {
return true;
}
return false;
}
private void addBefore(Node<AnyType> previousNode, AnyType newNode) {
Node<AnyType> new_node = new Node<>(newNode, previousNode.myTail, previousNode);
new_node.myTail.myHead = new_node;
previousNode.myTail = new_node;
theSize++;
}
public boolean add(AnyType newVal) {
{
add(size(), newVal);
return true;
}
}
public boolean add(int index, AnyType newVal) {
addBefore(getNode(index, 0, size()), newVal);
return true;
}
private Node<AnyType> getNode(int index) {
return getNode(index, 0, size() - 1);
}
public Node<AnyType> get(AnyType nodeData) {
Node<AnyType> node = beginMarker;
while (node != endMarker) {
// Means node.data = nodeData
if (node.myData.equals(nodeData)) {
return node;
}
}
return null;
}
// Added method
private Node<AnyType> getNode(int index, int lower, int upper) {
Node<AnyType> x;
if (index < lower || index > upper)
throw new IndexOutOfBoundsException();
if (index < size() / 2) {
x = beginMarker.myHead;
for (int i = 0; i < index; i++)
x = x.myHead;
} else {
x = endMarker.myTail;
for (int i = size(); i > index; i--) {
x = x.myTail;
}
}
return x;
}
public void printList() {
Node temp = beginMarker.myHead;
while (temp != null) {
System.out.println(temp.myData);
temp = temp.myHead;
}
}
public java.util.Iterator<AnyType> iterator() {
return new LinkedListIterator();
}
public void remove(AnyType removeVal) {
/*
* if(node.myData.equals(nodeData))
*
* MyLinkedList testList = new MyLinkedList();
*
* Node temp = testList.beginMarker.myData; while(temp != null){
*
* if(temp == removeVal){ temp.myTail = temp.myHead; temp.myHead =
* temp.myTail; } else{ temp.myHead = temp; }
*
*
* }
*/
}
private class LinkedListIterator implements java.util.Iterator<AnyType> {
private Node<AnyType> node_ = beginMarker;
public void remove() {
}
public boolean hasNext() {
if (node_.myHead != null) {
return true;
}
return false;
}
public AnyType next() {
if (!hasNext()) {
return null;
}
node_ = node_.myHead;
return node_.myData;
}
}
private static void testListIntegers() {
MyLinkedList<Integer> testList = new MyLinkedList<Integer>();
testList.add(new Integer(5));
testList.add(new Integer(4));
testList.add(new Integer(3));
System.out.println(" We have so far inserted " + testList.size() + " elements in the list");
testList.remove(4);
System.out.println(" Now, there is only " + testList.size() + " elements left in the list");
testList.add(1, new Integer(7));
testList.add(2, new Integer(8));
System.out.println(" About to print content of the list");
testList.printList();
}
private static void testListStrings() {
MyLinkedList<String> testList = new MyLinkedList<String>();
testList.add(new String("hello"));
testList.add(new String("this is"));
testList.add(new String("cs3345 project 2"));
System.out.println(" We have so far inserted " + testList.size() + " elements in the list");
testList.remove("this is");
System.out.println(" Now, there is only " + testList.size() + " elements left in the list");
testList.add(1, "a modified version of");
testList.add(2, "cs3345 project 2, call it version 2");
System.out.println(" About to print content of the list");
testList.printList();
}
public static void main(String args[]) throws Exception {
// Add whatever code you need here
// However, you will need to call both testListIntegers()
// and testListStrings()
testListIntegers();
testListStrings();
}
}
The output is as follows:
We have so far inserted 3 elements in the list
Now, there is only 3 elements left in the list
About to print content of the list
8
7
3
4
5
We have so far inserted 3 elements in the list
Now, there is only 3 elements left in the list
About to print content of the list
cs3345 project 2, call it version 2
a modified version of
cs3345 project 2
this is
hello
Problem is with addBefore method:
private void addBefore(Node<AnyType> previousNode, AnyType newNode) {
Node<AnyType> new_node = new Node<>(newNode, previousNode.myTail, previousNode);
new_node.myTail.myHead = new_node;
previousNode.myTail = new_node;
theSize++;
}
It is the same like:
private void addBefore(Node<AnyType> previousNode, AnyType newNode) {
Node<AnyType> new_node = new Node<>(newNode, previousNode.myTail, previousNode);
previousNode.myHead = new_node;
previousNode.myTail = new_node;
theSize++;
}
So basically you are breaking doubly linked list.
Edit:
According to algorithm described here this method should look like:
private void addBefore(Node<AnyType> previousNode, AnyType newNode) {
Node<AnyType> new_node = new Node<>(newNode, previousNode, previousNode.myTail);
if(previousNode.myTail==null){
beginMarker.myHead = new_node;
} else {
previousNode.myTail.myHead = new_node;
}
previousNode.myTail = new_node;
theSize++;
}
See that your list is indexed from 0 so the output should be:
5
7
8
4
3
And next problem is in printList method (infinite loop) because somewhere is wrong usage of your begin/end marker.
adding theSize--; at the end of the remove method should decrease the elements from 3 to 1

Getting node from adjacency list while traversing Depth First Search - Java

I am trying to get this code running as fast as possible when traversing through my stack of my DFS currently the input files are like so:
0 2
2 1
1 4
4 5
5 6
10 8
8 9
9 6
7 6
3 4
0 1
3 9
0 4
Where my Maze class will tie the numbers together and create a graph for me. After the graph is created my DFS class runs through traversing giving one or all solutions to the .txt file submitted.I have recently altered my Maze class as for it to run more efficiently but am being thrown errors and the data is parsing through to my DFS to be outputted. My new Maze class is as follows:
import java.io.*;
import java.util.*;
public class Maze {
private final Map<Integer, Set<Integer>> adjList = new HashMap<>();
/**
* The main constructor that takes a String for reading maze file.
*
* #param file
*/
public Maze(File file) throws FileNotFoundException {
try (Scanner scan = new Scanner(file)) {
while (scan.hasNextInt()) {
int node1 = scan.nextInt();
int node2 = scan.nextInt();
this.connect(node1, node2);
this.connect(node2, node1);
}
}
}
/**
* Makes a unidirectional connection from node1 to node2.
*/
private void connect(int node1, int node2) {
if (!this.adjList.containsKey(node1)) {
this.adjList.put(node1, new HashSet<Integer>());
}
this.adjList.get(node1).add(node2);
}
/**
* Returns a human-readable description of the adjacency lists.
*/
public String toString() {
StringBuilder s = new StringBuilder();
for (Map.Entry<Integer, Set<Integer>> adj : this.adjList.entrySet()) {
int from = adj.getKey();
Set<Integer> to = adj.getValue();
s.append(from).append(" connected to ").append(to).append('\n');
}
return s.toString();
}
/**
* Returns the set of nodes connected to a particular node.
*
* #param node - the node whose neighbors should be fetched
*/
public Iterable<Integer> getadjList(int node) {
return Collections.unmodifiableSet(adjList.get(node));
}
/**
* Demonstration of file reading.
*/
public static void main(String[] args) throws FileNotFoundException {
System.err.print("Enter File: ");
Scanner scanFile = new Scanner(System.in);
String file = scanFile.nextLine();
Maze m = new Maze(new File(file));
System.out.println(m);
}
}
My question is how do I pull the current node to my DFS class for my graph, I have tried a few things like :
maze.adjList.getNode()
maze.getadjList.get(node)
maze.adjList.get(node)
EDIT:: DFS class is below if it helps:
import java.io.*;
import java.util.*;
public class DFS {
//starting node, the route to the next node, has node been visited
private int startNode;
private int goalNode;
private int[] route;
private boolean[] visited;
// 2 main arguments - Maze File & user input
public DFS(Maze maze, int input) {
int startNode = 0;
int goalNode = 1;
route = new int[maze.adjList.getNode()];
visited = new boolean[maze.adjList.getNode()];
//Takes user's input and runs desired function
if(input == 1){
findOne(maze, startNode, goalNode);
}
else if (input == 2){
findAll(maze, startNode, goalNode);
}
else {
System.out.println("input invalid. No Solution Returned");
}
}
//Put path to goal in the stack
public Stack<Integer> route(int toGoalNode) {
if (!visited[toGoalNode]) {
return null;
}
Stack<Integer> pathStack = new Stack<Integer>();
for (int routeGoalNode = toGoalNode; routeGoalNode != startNode; routeGoalNode = route[routeGoalNode]) {
pathStack.push(routeGoalNode);
}
pathStack.push(startNode);
reverseStack(pathStack);
return pathStack;
}
//Reverse the stack
public void reverseStack(Stack<Integer> stackToBeReverse) {
if (stackToBeReverse.isEmpty()) {
return;
}
int bottom = popBottomStack(stackToBeReverse);
reverseStack(stackToBeReverse);
stackToBeReverse.push(bottom);
}
//Pop the bottom of the stack
private int popBottomStack(Stack<Integer> stackToBeReverse) {
int popTopStack = stackToBeReverse.pop();
if (stackToBeReverse.isEmpty()) {
return popTopStack;
} else {
int bottomStack = popBottomStack(stackToBeReverse);
stackToBeReverse.push(popTopStack);
return bottomStack;
}
}
//performs DFS and unsets visited to give the result of all paths
private void findAll(Maze maze, int node, int goal) {
visited[node] = true;
if(node == goal) {
printPath(goal);
} else {
for (int con : maze.getadjList(node)) {
if (!visited[con]) {
route[con] = node;
findAll(maze, con, goal);
}
}
}
visited[node] = false;
}
//performs DFS and maintains visited marker giving only one path
private void findOne(Maze maze, int node, int goal) {
visited[node] = true;
for (int con : maze.getadjList(node)) {
if (!visited[con]) {
route[con] = node;
findOne(maze, con, goal);
}
}
}
//Traverse the connections to the goal and print the path taken
public void printPath( int toGoal) {
int goalNode = 1;
if (visited[toGoal]) {
System.out.println("Completed Path: ");
for (int t : route(toGoal)) {
if (t == toGoal) {
System.out.print(t);
} else {
System.out.print(t + " -> ");
}
}
System.out.println();
}
}
public static void main(String[] args){
Scanner scanFile = new Scanner(System.in);
int goalNode = 1;
System.out.print("Enter maze file: ");
String file = scanFile.nextLine();
Maze maze = new Maze(new File(file));
Scanner scanInt = new Scanner(System.in);
System.out.print("Enter desired feedback (1 = one soultion, 2 = all): ");
int input = scanInt.nextInt();
maze.toString();
System.out.println(maze);
DFS dfs = new DFS(maze, input);
dfs.printPath(goalNode);
}
}
Since the adjacency list adjList is a private member, you would write a method in Maze for exposing elements of that list to DFS.
public Set<Integer> getNode(int node) {
return Collections.unmodifiableSet(adjList.get(node));
}
You seem to need the number of nodes also, that would be another method like:
public int getNumberOfNodes() {
return adjList.size();
}

Categories

Resources