How can I get out of this infinite loop? - recursion

I am writing a recursive function to find the index of a node in a linked list. It looks like this:
function indexAt(node, collection, linkedList) {
let index = 0;
if (node === nodeAt(index, linkedList,collection)) {
return index
} else {
index ++
return indexAt(node, collection, linkedList)
}
}
It calls on the nodeAt function, which looks like this:
function nodeAt(index, linkedList, collection) {
let node = collection[linkedList];
for (let i=0; i < index; i++) {
node = next(node, collection)
}
return node
}
This works fine when the index is 0, but when it is anything else, it increments the index, then sets it back to 0, entering an infinite loop. How can I fix this without fundamentally altering the code?

Well at the start of the function you reset the index to 0. So every time it recurs, it resets the index, thus causing your infinite loop.
An easy fix is to declare the index variable outside the function. That will ensure it's not reset every time the function recurs.
A better fix would be to pass the index as an argument to the function so that it will always keep track of its own index.

Just make a helper that holds the extra variable:
function indexAt(node, collection, linkedList) {
function indexAt(index, node, collection, linkedList) {
if (node === nodeAt(index, linkedList, collection)) {
return index
} else {
return indexAt(index + 1, node, collection, linkedList)
}
}
return indexAt(0, node, collection, linkedList);
}
Now you count from 0...n and make nodeAt start at the beginning each time making this O(n^2). A much better way would be that the helper has the current node, initialized at collection[linkedList] and stepping with next(currentNode) and index + 1 until node === currentNode. That would be a O(n) solution. indexAt doesn't really need to be recursive unless it is a requirement.

Related

Confusion about recursion for BST

Is there an easy way to understand when you can just call the recursive method vs having to set that recursive method to a variable?
For example...
Just calling the recursive function to traverse:
self.recurse(node.left)
self.recurse(node.right)
Having to set the recursive function to node.left and node.right:
node.left = self.recurse(node.left)
node.right = self.recurse(node.left)
Another example is to delete a node in a bst you have to set the recursive function to root.left and root.right... I get it but not completely... is there a easy way to understand when you can just call the recursive function vs having to set it to node.left, node.right..etc...?
def deleteNode(self, root: TreeNode, key:int) -> TreeNode:
if not root:
return root
if key < root.val:
root.left = self.deleteNode(root.left,key)
elif key > root.val:
root.right = self.deleteNode(root.right,key)
else:
if not root.left:
return root.right
elif not root.right:
return root.left
root.val = self.successor(root.right)
root.right = self.deleteNode(root.right,root.val)
return root
To understand this two above scenarios (Simple Recursive Call and Set result of Recursive call to a Variable), just try to understand the following code/function.
Let's say, you have a TREE, which contains a value in every node where value is either negative or positive. Now let's say, you are going to count how many nodes are there whose value is Positive.
The TREE structure for this problem is like following:
TREE{
Integer val;
TREE left = right = null;
}
Now you gave me this problem to solve. And I wrote a function/method which will count nodes with positive value. The function is following:
Integer countNodes(TREE node){
if(node == null){
return 0;
}else{
Integer count = 0; // which will count how many nodes are there with positive value
if(node.val >= 0){
count += 1; // if the value is positive I incremented count
}
// and we are checking every other nodes present in the TREE
getCount(node.left);
getCount(node.right);
// and return the final result
return count;
}
}
Now I returned my function to you, and you executed! But what! There is a big WRONG! It's giving wrong result, over and over again!!
But why???
Let's analysis.
if(node.val >= 0){
count += 1;
}
Up to that we were right! But the problem was, we were incremented the count, but wasn't use it! Each time we was calling function recursively, a new stack frame was created, a new variable named "count" was created, but we were not using this value!
To use the variable "count", we need to re-initialize the returned value of every recursive call to the variable, that's the way we can keep a link between the current stack-frame and the previous stack-frame and the previous of previous stack-frame and goes onn!.. we need to change little-bit in the function countNodes like following:
if(node.val >= 0){
count += 1;
}
count += getCount(node.left); // re-initialize count in each recursive call
count += getCount(node.right); // re-initialize count in each recursive call
return count;
Now everything we'll be alright! this code will work perfectly!
The above scenarios is implies your problem.
self.recurse(node.left)
self.recurse(node.right)
this is nothing but simple traversing over all the nodes.
But if you need to use the returned result of every recursion, you need to initialize/re-initialize the returned value to a variable. That's what is happening with:
node.left = self.recurse(node.left)
node.right = self.recurse(node.left)
I HOPE this long (bit long) explanation will help to go further. Happy Coding! : )

Not understood return behavior of recursive function with closure

The foundations of my programming "skills" are shaking.. I don't know if this behavior is caused by the recursion, closure or something else, but this is by far the weirdest thing I've seen so far.
My original intention was to use recursion to count the parents of dom element. The closure is implemented to store my counter and recursion would increase it for every parent that is not equal to div#wrapper. And it works - once. For the first element (having only 1 parent - it returns 1) However the second time it returns undefined. for the sake of testing I came up with this rig:
let parents = countParents();
let pathLength = parents(3);
function countParents() {
let counter = 0;
return function nextParent(node) {
let parent = node - 1;
counter++;
if (parent === 1)
return 'WATAFAK';
else
nextParent(parent);
}
}
console.log(pathLength);
I am actually questioning my eyes (it's late, been programming for a while now), but this function returns undefined. HOW is that possible?
function countParents() {
let counter = 0;
return function nextParent(node) {
let parent = node - 1;
counter++;
if (parent === 1)
return 'WATAFAK';
else
nextParent(parent); // call nextParent(parent) and throw away result
return undefined; // invisible line in every function
}
return undefined; // invisible line in every function (never reached)
}
If you wanted the result of the recursion to be the result you must add return in front of it. How it is now it's only for side effects and it's pretty much dead code.
Since the else branch doesn't return all functions have a invisible return undefined, just before its block ends.

Recursive Function into Non-Recursive Function?

I have the following recursive Grails function:
private boolean isCyclic(TreeNode node) {
boolean cyclic = false
def myParents = this.parents
// if there are parents of this node
if (myParents.size() != 0) {
// if the new node is in the parents set of this node
if (myParents.contains(node)) {
cyclic = true
return cyclic
}
else {
// go into each parent of this node and test if new node is contained in their parents
myParents.each { parent ->
log.debug "go to parent: "+parent.name
if (cyclic) {
return cyclic
}
cyclic = parent.isCyclic(node)
}
}
}
return cyclic
}
How can I transform this function into a non-recursive function?
I think your code above is a contains method, rather than a cyclic check...
However here's a quick example of both a contains method and a cyclic check in an iterative style... Fingers crossed they're right
def contains( TreeNode node ) {
// if this node is the one we're looking for, return true
if( node == this ) {
return true
}
// A queue of nodes to work on
def parentQueue = this.parents as Queue
// A set of nodes we've seen (to avoid loops)
def seen = [ this ] as Set
// While we have nodes to look for
while( parentQueue ) {
// get the next node
def next = parentQueue.pop()
// Check if it's the one we're looking for
if( next == node ) return true
// And if not, add it's parents to the queue
// assuming we've not seen it before
if( !seen.contains( next ) ) {
next.parents.each { parentQueue.offer( it ) }
}
}
// Not found
return false
}
def isCyclic() {
// A queue of nodes to work on
def parentQueue = this.parents as Queue
// A set of nodes we've seen (to detect loops)
def seen = [ this ] as Set
// While we have nodes to look for
while( parentQueue ) {
// Look at the next element in the queue
def next = parentQueue.pop()
// If we've seen it before, it's cyclic
if( seen.contains( next ) ) return true
// Otherwise, record we've seen this node
seen << next
// And add its parents tothe queue
next.parents.each { parentQueue.offer( it ) }
}
// All done, not cyclic
return false
}
Tom Moertel wrote solution for this problem on his blog.
He clearly explained the transformation of recursive function into the iterative (link).
I have used his approach to transform my own functions when I needed and I was convinced that is correct.
I hope that helps.
Basically to transform a recursive function into an iterative function you should notice which is the case base(this case is the stop case of recursive function), put all functionality into a loop and use that base case as exit condition of used loop.
Perhaps i didn't explain it very well but every recursive function has an iterative function.

Backtracking recursively with multiple solutions

function BACKTRACKING-SEARCH(csp) returns a solution, or failure
return RECURSIVE- BACKTRACKING({ }, csp)
function RECURSIVE-BACKTRACKING(assignment,csp) returns a solution, or failure
if assignment is complete then
return assignment
var ←SELECT-UNASSIGNED-VARIABLE(VARIABLES[csp],assignment,csp)
for each value in ORDER-DOMAIN-VALUES(var,assignment,csp) do
if value is consistent with assignment according to CONSTRAINTS[csp] then
add {var = value} to assignment
result ← RECURSIVE-BACKTRACKING(assignment, csp)
if result ̸= failure then
return result
remove {var = value} from assignment
return failure
This is a backtracking recursion algorythm pseudocode from AIMA. However, I don't understand if it returns ALL possible solutions or just first one found. In case it is the last option, could you please help me modify it to return a list of possible solutions instead (or at least updating some global list).
EDIT: I implemented this algorithm in Java. However, there is one problem:
if I don't return assignment, but save it in result instead, the recursion stop condition fails (i.e. it doesn't exist anymore). How can I implement another stop-condition? Maybe I should return true in the end?
Here is my code :
/**
* The actual backtracking. Unfortunately, I don't have time to implement LCV or MCV,
* therefore it will be just ordinary variable-by-variable search.
* #param line
* #param onePossibleSituation
* #param result
*/
public static boolean recursiveBacktrack(Line line, ArrayList<Integer> onePossibleSituation, ArrayList<ArrayList<Integer>> result){
if (onePossibleSituation.size() == line.getNumOfVars()){
// instead of return(assignment)
ArrayList<Integer> situationCopy = new ArrayList<Integer>();
situationCopy.addAll(onePossibleSituation);
result.add(situationCopy);
onePossibleSituation.clear();
}
Block variableToAssign = null;
// iterate through all variables and choose one unassigned
for(int i = 0; i < line.getNumOfVars(); i++){
if(!line.getCspMiniTaskVariables().get(i).isAssigned()){
variableToAssign = line.getCspMiniTaskVariables().get(i);
break;
}
}
// for each domain value for given block
for (int i = line.getCspMiniTaskDomains().get(variableToAssign.getID())[0];
i <= line.getCspMiniTaskDomains().get(variableToAssign.getID())[0]; i++){
if(!areThereConflicts(line, onePossibleSituation)){
//complete the assignment
variableToAssign.setStartPositionTemporary(i);
variableToAssign.setAssigned(true);
onePossibleSituation.add(i);
//do backtracking
boolean isPossibleToPlaceIt = recursiveBacktrack(line,onePossibleSituation,result);
if(!isPossibleToPlaceIt){
return(false);
}
}
// unassign
variableToAssign.setStartPositionTemporary(-1);
variableToAssign.setAssigned(false);
onePossibleSituation.remove(i);
}
// end of backtracking
return(false);
}
This code checks if solution found and if it is, returns the solution. Otherwise, continue backtracking. That means, it returns the first solution found.
if result ̸= failure then
return result
remove {var = value} from assignment
You can modify it like that:
if result ̸= failure then
PRINT result // do not return, just save the result
remove {var = value} from assignment
Or, better, modify this part:
if assignment is complete then
print assignment
return assignment // print it and return
About edited question:
First, return true in the first if, so recursion will know that it found a solution. The second step, there is a mistake, probably:
if(!isPossibleToPlaceIt){
return(false);
}
Should be
if(isPossibleToPlaceIt){
return(true);
}
Because if your backtracking has found something, it returns true, which means you don't have to check anything else any longer.
EDIT#2: If you want to continue backtracking to find ALL solutions, just remove the whole previous if section with return:
//if(isPossibleToPlaceIt){
// return(true);
//}
So we will continue the search in any way.

Newbie on use of recursion in Groovy/traverse tree?

In our current application we have a need to traverse down a tree and capture all operators on a specific device (and child devices). A device could have child devices with also specific operators on it.
As i am new to the use of recursion in Groovy i am wondering if i am doing things right..?
Any pointer to help me learn better ways of doing things?
def listOperators(device) {
// list with all operator id's
def results = []
// closure to traverse down the tree
def getAllOperators = { aDevice->
if(aDevice) {
aDevice.operators.each { it ->
results << it.id
}
}
if (aDevice?.children) {
aDevice.children.each { child ->
results << owner.call(child)
}
}
}
// call the closure with the given device
getAllOperators(device)
// return list with unique results
return results.unique()
}
A couple things to note:
Doing the recursive call through owner is not a good idea. The definition of owner changes if the call is nested within another closure. It's error prone and has no advantages over just using the name. When the closure is a local variable, split its up the declaration and definition of the closure so the name is in scope. E.g.:
def getAllOperators
getAllOperators = { ...
You are appending the operators to a result list outside the recursive closure. But you are also appending the result of each recursive call to the same list. Either append to the list or store the results from each recursive call, but not both.
Here's a simpler alternative:
def listOperators(device) {
def results = []
if (device) {
results += device.operators*.id
device.children?.each { child ->
results += listOperators(child)
}
}
results.unique()
}

Resources