I want to use DFS to find all possible paths from one source vertex to a destination vertex. Being new to recursion, I am just completely lost in how I would have my recursive method perform such a function.
The code I have right now only finds one path and exits the method after the vertex had been found.
The code I have:
public Node DFSTime(Node node) {
// Boolean to check if the destination airport is found and then exit the
// recursive method
boolean ifreached = false;
// Check if the node is the destination airport
if (node.element.equals(destinationAirport)) {
stack.push(node);
return null;
} else {
int index = 0;
stack.push(node);
// Find the exact index of the node in the adjacency list
for (int i = 0; i < adjList.adjMatrix.size(); i++) {
if (adjList.adjMatrix.get(i).head.element.equals(node.element) == true) {
index = i;
break;
}
}
// Check if the node is already visited
if (visited.contains(node.element.toString()) == false) {
visited.add(node.element.toString());
}
Node currentNode = adjList.adjMatrix.get(index).head.nextNode;
// counter to keep track of the number of neighbors visited
int counter = 0;
// Iterating through the linked list at adjMatrix[index]
while (currentNode != null) {
// If visited then skip
if (visited.contains(currentNode.element) == false) {
previousAirport = node.element.toString();
Node temp = DFSTime(currentNode);
//If the destination airport is found then exit the recursive method
if (temp == null) {
ifreached = true;
break;
}
}
//Iterate to the next neighbor
currentNode = currentNode.nextNode;
counter++;
}
// If the destination airport is not found after iterating through the neighbors
// then pop the stack
if (counter == adjList.adjMatrix.get(index).size - 1) {
Node temp = stack.pop();
previousAirport = temp.element.toString();
visited.remove(temp.element.toString());
return temp;
}
}
// If the destination airport is found then return null
if (ifreached == true) {
return null;
}
return node;
}
This question is similar to another question I asked, and so I basically tried to change a few things from that question for my recursive method.
The Stack is a linked list stack I implemented. And the adjacency list is an ArrayList of Linked Lists.
Related
I have a Trie which looks like this:
Root
/ \
b c
/ / \
a a h
/ / / \
t t a e
/ /
t e
/ \
r s
/ \
s e
I'm trying to implement a DFS, and BFS. The BFS works fine, using a queue:
public String breadthFirstSearch() {
//FIFO Queue to hold nodes
Queue<TrieNode> nodeQueue = new LinkedList<TrieNode>();
//Output array
ArrayList<Integer> out = new ArrayList<Integer>();
//Start from root
nodeQueue.add(this.root);
//While queue is not empty
while (nodeQueue.isEmpty() == false) {
//Remove and return first queue element
TrieNode current = nodeQueue.poll();
//For node's children
for (int i=0; i<26; i++) {
//If not null
if (current.offspring[i] != null) {
//Add node to queue
nodeQueue.add(current.offspring[i]);
//Add node's index (char) to output array
out.add(i);
}
}
}
//Return result
return indexArrayToString(out);
}
Output:
b,c,a,a,h,t,t,a,e,t,e,r,s,s,e
Now, I'm trying to implement the DFS (same algorithm, but using a stack) however the output isn't correct:
public String depthFirstSearch() {
//LIFO Stack to hold nodes
Stack<TrieNode> nodeStack = new Stack<TrieNode>();
//Output array
ArrayList<Integer> out = new ArrayList<Integer>();
//Start from root
nodeStack.push(this.root);
//While stack is not empty
while (nodeStack.isEmpty() == false) {
//Remove and return first stack element
TrieNode current = nodeStack.pop();
//For node's children
for (int i=0; i<26; i++) {
//If not null
if (current.offspring[i] != null) {
//Add node to stack
nodeStack.push(current.offspring[i]);
//Add node's index (char) to output array
out.add(i);
}
}
}
//Return result
return indexArrayToString(out);
}
This gives:
b,c,a,h,a,e,e,r,s,e,s,t,t,a,t
When I want it to give:
t,a,b,t,a,t,a,s,r,e,s,e,e,h,c
I can't figure out what's going wrong.
I have implemented the map-based approach that I mentioned in my comment, i.e. without modifying the original TrieNode class:
public String depthFirstSearch() {
//LIFO Stack to hold nodes
Stack<TrieNode> nodeStack = new Stack<TrieNode>();
//keep set of processed nodes (processed node is a node whose children were already pushed into the stack)
Set<TrieNode> processed = new HashSet<TrieNode>();
//boolean for checking presence of at least one child
boolean hasChild=false;
//map for trienode->char
Map<TrieNode, Integer> map = new HashMap<TrieNode, Integer>();
//Output array
List<Integer> out = new ArrayList<Integer>();
//Start from root
nodeStack.push(this.root);
//While stack is not empty
while (nodeStack.isEmpty() == false) {
//Peek at the top of stack
TrieNode topNode = nodeStack.peek();
//if it is not processed AND if it has at least one child, push its children into the stack from right to left. otherwise pop the stack
hasChild=false;
if(!processed.contains(topNode))
{
for (int i=25; i>=0; i--)
{
//If not null
if (topNode.offspring[i] != null)
{
//Add node to stack and map
nodeStack.push(topNode.offspring[i]);
map.put(topNode.offspring[i], i);
hasChild=true;
}
}//end for
processed.add(topNode); //after discovering all children, put the top into set of processed nodes
if(!hasChild) //top node has no children so we pop it and put into the list
{
TrieNode popNode = nodeStack.pop();
if(map.get(popNode)!=null)
out.add(map.get(popNode));
}
}
else //the node has been processed already so we pop it and put into the list
{
TrieNode popNode = nodeStack.pop();
if(map.get(popNode)!=null)
out.add(map.get(popNode));
}
}//end while stack not empty
//Return result
return indexArrayToString(out);
}//end method
To get the output that you wanted, you need to think about when a node is added to the out list. In your code, you start at the root and iterate throught it's offspring in a kind-of recursive style while adding them directly to your output. Therefore your output has more in common with a BFS than a DFS.
Although there are very simple DFS implementations like
DFS(TrieNode current){
for(int i = 26; i >= 0; i--){
if(current.offspring[i] != null){
DFS(current.offspring[i]);
}
}
out.add(current);
}
if you want to keep most of your code for any reason, you could create a second stack that keeps track for you where in the tree you are and when which node is supposed to be added to the output.
Explicitly, this could look something like this:
public String depthFirstSearch() {
//LIFO Stack to hold nodes
Stack<TrieNode> nodeStack = new Stack<TrieNode>();
//Second stack that keeps track of visited nodes
Stack<TrieNode> helpStack = new Stack<TrieNode>();
//Output array
ArrayList<Integer> out = new ArrayList<Integer>();
//Start from root
nodeStack.push(this.root);
//While stack is not empty
while (nodeStack.isEmpty() == false) {
//Remove and return first stack element
TrieNode current = nodeStack.peek();
//We visited this node -> push it on the second stack
helpStack.push(current);
//We want to add nodes to the output once we reach a leaf node, so we need a
//helper variable
boolean hasOffspring = false;
//For node's children - since we want to go the left path first we push the
//children in right-to-left fashion on the stack. Can vary with implementation.
for (int i=25; i>=0; i--) {
//If not null
if (current.offspring[i] != null) {
//Add node to stack
nodeStack.push(current.offspring[i]);
//not a leaf
hasOffspring = true;
}
}
//if we reached a leaf node add it and all previous nodes to the output until
//we reach a fork where we didn't already fo the other path
if(!hasOffspring){
TrieNode node1 = nodeStack.peek();
TrieNode node2 = helpStack.peek();
while(node1.equals(node2)){
nodeStack.pop();
helpStack.pop();
//Add node's index (char) to output array
out.add(node1);
//we are back at the root and completed the DFS
if(nodeStack.isEmpty() || helpStack.isEmpty()) break;
node1 = nodeStack.peek();
node2 = nodeStack.peek();
}
}
}
//Return result
return indexArrayToString(out);
}
The code makes no changes to the output and just reprints the original linked list and I don't know whether the problem is with my delete method or with the access specifiers I used for my Stack.
List item
Public static class Stack
{
Node first; *// newest node added*
private int size;
class Node
{
String item;
Node next;
}
public Node delete(int index,Stack list)
{
if (list.first== null) {
return null;
} else if (index == 0)
{
return list.first.next;
}
else
{
Node n = list.first;
for (int i = 0; i < index - 1; i++)
{
n = n.next;
if(i==index)
n.next = n.next.next;//skips over the existing element
}
return list.first;
}
}
}
//client test code
public static void main(String[] args) {
StdOut.print("Type the linked list:");
Stack list = new Stack();
int index;
String in=StdIn.readLine();
for(int i=0;i<=in.length();i++)
{
list.push(in);
}
StdOut.print("Type the index to be deleted:");
index=StdIn.readInt();
StdOut.println("Before deleting element at "+ index);
StdOut.println(in);
StdOut.println("After deleting element at "+ index);
StdOut.print(list.delete(index,list).item);
}
}
In your delete() function, you are returning list.first - which is pointing to the head node of the list, and not the Node first* //newest node added*, correct? I think you should just be returning from the function when the delete task is complete instead of returning null or a node.
Also, as you iterate through the list in the final else statement, you should move the n = n.next; line below the index check.
Your delete() function would look something like this:
public Node delete(int index,Stack list)
{
if (list.first== null)
{
return;
} else if (index == 0)
{
return;
}
else
{
Node n = list.first;
for (int i = 0; i < index; i++)
{
//If the next Node of the current node is +1 the current index
if(i+1==index)
{
n.next = n.next.next;//skips over the existing element
return;
}
n = n.next;
}
return;
}
}
And :
list.delete(index,list).item; //call the delete function
StdOut.println("After deleting element at "+ index);
list.print(); //Print the list using its print function (assuming you have one)
I hope this helps!
I am working on Singly linked lists and have coded a function that will delete an element at a particular position in the linked list.
Problems I am facing is I am unable to delete an element if there is only one element left in the linked list.
Here is my code:
void deleteAtPosN(int position) {
int i = 1;
LinkedList temp = head;
if (position <= 0)
return;
while (i < position - 1) {
temp = temp.next;
++i;
}
if (temp == null) {
System.out.println("list is empty");
} else if (i == position) {
temp = null;
} else {
LinkedList deleteElement = temp.next;
temp.next = deleteElement.next;
}
}
Why your code does not work
When you get to the last item you set temp to null, but that does not affect the linked list in memory, it just changes your local copy to be equal to null.
How to fix
You want to keep a reference to the previous element, and modify it's next, instead of keeping the current item
Pseudocode
fun removeN(index) {
var current = head
var last = null
for (int i = 0; i < index; i++) {
last = current
current = current.next
i++
}
if (last == null) {
// We are at the head of the list
head = current.next
} else {
last.next = current.next
}
}
You have an iterative solution by #jrtapsell that keeps track of the last and the current pointers. Here is a recursive solution that keeps track of all the last pointers via the recursive call stack. The recursive solution is easier to understand and write, but the iterative solution is better IMO because it has O(1) extra memory overhead as opposed to O(N).
//zero based indexing, assumes position >= 0
public void deleteAtPosN(int position)
{
head = deleteAtPosNHelper(head, position);
}
//assumes position >= 0
private LinkedList deleteAtPosNHelper(LinkedList current, int position)
{
if (current == null)
{
return null;
}
else if (position == 0)
{
return current->next;
}
else
{
current->next = deleteAtPosHelper(current->next, --position);
return current;
}
}
This how you would add an item:
public void insert (Object item)
{
Link add = new Link();
add.data = item;
add.next = head;
_head = add;
++_listsize;
}
But how do you add an item at a given position. So far this is what I got:
public void insert (Object item, int pos)
{
Link add = new Link();
int ix = pos - 1;
add.next = _head;
for (int i = _listsize - 1; i >= ix; --i)
add = add.next;
add.data = item;
_head = add;
++_listsize;
}
This will insert the item correctly if it is sequential, but let say I am given a position which is in the middle, what it will do it will insert the item but it will completely cut off (or delete the rest). For example:
insert at 1:
a
insert at 2:
b
a
insert at 3:
c
b
a
insert at 2:
d
a
You should do something like this:
public void insert (Object item, int pos)
{
Link add = new Link();
int ix = pos - 1;
Link cur = _head;
for (int i = 0; i < _list_size; i++) {
if(i == ix) {
add.next = cur.next;
cur.next = add;
}
cur = cur.next;
}
++_listsize;
}
It seems you have not correctly inserted the new Link into the list. When you do that, you need to find the Link at the given position as well as the Link at the previous position. Then only you can set the previous.next = add and add.next = position.
Below is the updated method that does the task.
public void insert (Object item)
{
Link add = new Link();
add.data = item;
add.next = _head;
_head = add;
++_listsize;
}
public void insert (Object item, int pos)
{
Link add = new Link();
add.data = item;
int ix = pos - 1;
add.next = _head;
Link previous = _head;
for (int i = _listsize - 1; i > ix; --i) {
previous = previous.next;
}
Link position = previous.next;
previous.next = add;
add.next = position;
++_listsize;
}
Use add( int index, E element), which insert the element at the specified index : http://docs.oracle.com/javase/7/docs/api/java/util/LinkedList.html#add(int, E)
EDIT : if you're using LinkedList, of course ; with your own class, you have to store prev/next pointers and simply update them (previous node next's pointer should point to the new element, and next node previous's pointer should point to the new element too)
It is definetly possible. But what would matter most is deciding at which position to insert new element because after each insertion the list would change and position of new element coming will have to be decided appropriately. You can try this
insertat=head;
for(i=0;i<pos;i++){
insertat=insertat.next;
}
add.next=insertat.next;
insertat.next=add;
listsize++;
You need a temporary variable that start from the head, traverse each node until the desired position or the end of the list, then insert the new node.
Since it is a homework exercise, I will only post pseudo code:
if pos < 0
//define what to do here...
return
end if
if pos == 0
//inserting at the beginning
insert(item)
return
end if
Link temp <- head
int index <- 0
while index < pos and temp->next != null
temp <- temp->next
index <- index + 1
end while
//now you're at your desired location or at the end of the list
Link newLink <- new Link
newLink->data <- item
newLink->next <- temp->next
temp->next <- newLink
After attempting alone the implementation of the concept, you can consider the open-source research. One of the best things you can do with open source is learn from it, study the implementation of java.util.LinkedList,
following the logic of the method add (int index, E element) { http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/java/util/LinkedList.java#360 }, you can divide in;
1) Get where the element will be added, in your case "link"
http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/java/util/LinkedList.java#380
2) and you can examine the code that links the elements following the logic "before adding" in the code snippet
http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/java/util/LinkedList.java#794
So, you will understand the logic behind the algorithm and will be able to perform your own implementation
My solution is not as clean as it will be with recursion but if you are testing more than 50,000 elements on the list go with an iterative solution. or you can modify the JVM and change the stack size.
Because you can get a stack overflow just because you will pass the capacity of activation records in the stack. Think about the worst case scenario that you will do an insert at the end of the list.
/**
* Inserts the specified element at the specified position in this list.
*
* #param :index the desire position starting from 0 2,3,4,5
* #param :data the content of the new node
* #return Boolean: if the insertion was successfully return true otherwise false
*/
public boolean add(int index, T data) {
/*Add to the end of the list*/
if (index == size()) {
add(data);
return true;
}
/*Empty list and index bigger than 0*/
else if (this.front == null && index != 0) {
return false;
} else {
Node<T> tempNode = this.front;
while (tempNode != null && tempNode.next != null && --index != 0) {
tempNode = tempNode.next;
}
if (index != 0) {
return false;
} else {
Node<T> newNode = new Node<T>(data);
/*Empty list,and index is 0*/
if (tempNode == null) {
this.front = newNode;
} else {
newNode.next = tempNode.next;
tempNode.next = newNode;
}
}
}
return true;
}
I'm working with a linked list in java and I need to take a list of x objects and move the odd positioned objects to the end of the list.
I have to do it by using linking, no new nodes, no list.data exchanges.
I feel like I have a decent handle when I'm moving stuff from one list to another, but traversing and appending with references to only one list is really tough.
Here's the actual question ---
Write a method shift that rearranges the elements of a list of integers by moving to the end of the list all values that are in odd-numbered positions and otherwise preserving list order. For example, suppose a variable list stores the following values:
[0, 1, 2, 3, 4, 5, 6, 7]
The call of list.shift(); should rearrange the list to be:
[0, 2, 4, 6, 1, 3, 5, 7]
you must solve this problem by rearranging the links of the list.
below is the class that I need to write the method before (with the aforementioned restrictions.
I can't really come up with a plan of attack.
// A LinkedIntList object can be used to store a list of integers.
public class LinkedIntList {
private ListNode front; // node holding first value in list (null if empty)
private String name = "front"; // string to print for front of list
// Constructs an empty list.
public LinkedIntList() {
front = null;
}
// Constructs a list containing the given elements.
// For quick initialization via Practice-It test cases.
public LinkedIntList(int... elements) {
this("front", elements);
}
public LinkedIntList(String name, int... elements) {
this.name = name;
if (elements.length > 0) {
front = new ListNode(elements[0]);
ListNode current = front;
for (int i = 1; i < elements.length; i++) {
current.next = new ListNode(elements[i]);
current = current.next;
}
}
}
// Constructs a list containing the given front node.
// For quick initialization via Practice-It ListNode test cases.
private LinkedIntList(String name, ListNode front) {
this.name = name;
this.front = front;
}
// Appends the given value to the end of the list.
public void add(int value) {
if (front == null) {
front = new ListNode(value, front);
} else {
ListNode current = front;
while (current.next != null) {
current = current.next;
}
current.next = new ListNode(value);
}
}
// Inserts the given value at the given index in the list.
// Precondition: 0 <= index <= size
public void add(int index, int value) {
if (index == 0) {
front = new ListNode(value, front);
} else {
ListNode current = front;
for (int i = 0; i < index - 1; i++) {
current = current.next;
}
current.next = new ListNode(value, current.next);
}
}
public boolean equals(Object o) {
if (o instanceof LinkedIntList) {
LinkedIntList other = (LinkedIntList) o;
return toString().equals(other.toString()); // hackish
} else {
return false;
}
}
// Returns the integer at the given index in the list.
// Precondition: 0 <= index < size
public int get(int index) {
ListNode current = front;
for (int i = 0; i < index; i++) {
current = current.next;
}
return current.data;
}
// Removes the value at the given index from the list.
// Precondition: 0 <= index < size
public void remove(int index) {
if (index == 0) {
front = front.next;
} else {
ListNode current = front;
for (int i = 0; i < index - 1; i++) {
current = current.next;
}
current.next = current.next.next;
}
}
// Returns the number of elements in the list.
public int size() {
int count = 0;
ListNode current = front;
while (current != null) {
count++;
current = current.next;
}
return count;
}
// Returns a text representation of the list, giving
// indications as to the nodes and link structure of the list.
// Detects student bugs where the student has inserted a cycle
// into the list.
public String toFormattedString() {
ListNode.clearCycleData();
String result = this.name;
ListNode current = front;
boolean cycle = false;
while (current != null) {
result += " -> [" + current.data + "]";
if (current.cycle) {
result += " (cycle!)";
cycle = true;
break;
}
current = current.__gotoNext();
}
if (!cycle) {
result += " /";
}
return result;
}
// Returns a text representation of the list.
public String toString() {
return toFormattedString();
}
// Returns a shorter, more "java.util.LinkedList"-like text representation of the list.
public String toStringShort() {
ListNode.clearCycleData();
String result = "[";
ListNode current = front;
boolean cycle = false;
while (current != null) {
if (result.length() > 1) {
result += ", ";
}
result += current.data;
if (current.cycle) {
result += " (cycle!)";
cycle = true;
break;
}
current = current.__gotoNext();
}
if (!cycle) {
result += "]";
}
return result;
}
// ListNode is a class for storing a single node of a linked list. This
// node class is for a list of integer values.
// Most of the icky code is related to the task of figuring out
// if the student has accidentally created a cycle by pointing a later part of the list back to an earlier part.
public static class ListNode {
private static final List<ListNode> ALL_NODES = new ArrayList<ListNode>();
public static void clearCycleData() {
for (ListNode node : ALL_NODES) {
node.visited = false;
node.cycle = false;
}
}
public int data; // data stored in this node
public ListNode next; // link to next node in the list
public boolean visited; // has this node been seen yet?
public boolean cycle; // is there a cycle at this node?
// post: constructs a node with data 0 and null link
public ListNode() {
this(0, null);
}
// post: constructs a node with given data and null link
public ListNode(int data) {
this(data, null);
}
// post: constructs a node with given data and given link
public ListNode(int data, ListNode next) {
ALL_NODES.add(this);
this.data = data;
this.next = next;
this.visited = false;
this.cycle = false;
}
public ListNode __gotoNext() {
return __gotoNext(true);
}
public ListNode __gotoNext(boolean checkForCycle) {
if (checkForCycle) {
visited = true;
if (next != null) {
if (next.visited) {
// throw new IllegalStateException("cycle detected in list");
next.cycle = true;
}
next.visited = true;
}
}
return next;
}
}
// YOUR CODE GOES HERE
}
see it this way:
first we need some sort of cursor that will go through the list and point to our "current" node
second we need some boolean variable (i'll call it INV) initialized as FALSE ... everytime we move a node in the list, we invert INV
if you go through the list from the left, the second element is the first to be rearanged, so that will be our initial cursor position
lets take a reference on that element/node, and keep that reference as abort criteria
start of loop:
now remove the current node from the list and insert it at the end of the list (move to the end ... not that the cursor may not move with the node ...)
move the cursor to the node that is right of the former position of the node we just moved (if that exists)
if the current element is our abort criteria (first element we moved) we can assume the list is sorted now in the desired order -> we are finished -> exit the loop ... if it's not our abort criteria ... go on
evaluate "index of the cursor is even" to either TRUE or FALSE ... XOR that with INV
if the result is TRUE move the cursor to the next element ... if it's FALSE remove the node and insert it at the end (move it to the end)
do the loop
--
this approach will not preserve the order while we move through the list, but will have the list in the desired order when it finishes ...
the INV var is for compensation the index shifts when removing a node ... (0,1,2,3 ... if you remove the 1 and put it at the end, 2 will have an odd index, so if we invert that with every move, we get the "right" elements)