The recursion is sort of a \'divide and conquer\' style, it splits up while getting smaller (Tree data structure), and I want it to break completely if a violation is found,
Maybe you want to avoid recursion and replace it with a stack. This gives you the control to break out of the operation, while being able to do something that resembles a recursive operation. In fact you just emulate recursion by yourself.
I found a nice explanation here: http://haacked.com/archive/2007/03/04/Replacing_Recursion_With_a_Stack.aspx/
The best way to get out of a recursive loop when an error is encountered is to throw a runtime exception.
throw new RuntimeException("Help! Somebody debug me! I'm crashing!");
Of course, this kills your program, but you should employ range checking and algorithm analysis to make sure your recursion does not throw such an exception. One reason you might want to break out of a recursive algorithm is that you are running low on memory. Here, it is possible to determine how much memory your algorithm will use on the stack. If you are coding Java, say, compare that calculation to
getMemoryInfo.availMem().
Let's say you are using recursion to find n!. Your function looks something like this:
public long fact(int n)
{
long val = 1;
for (int i = 1, i<=n,i++)
return val *= fact(i);
return val;
}
Before you run it, check that you have (number of bytes in a long, 8 in Java) * n bytes in memory to hold the whole stack. Basically, with range and error checking in advance of the recursive method/function, you shouldn't need to break out. Depending on your algorithm, however, you may need to signal to the whole stack that you're good to go. If that's the case, Tom's answer works.
Unless recursive calls are being evaluated in parallel, you probably just need to add some logic to check the first recursive call's value prior to making the second (and subsequent, if not a binary tree structure) recursive call.
public abstract class Tree {
protected abstract boolean headIsViolation();
protected abstract boolean isLeaf();
public Tree getLeft();
public Tree getRight();
// Recursive
public boolean checkViolation() {
if(this.isLeaf()) {
return this.headIsViolation();
}
// If needed, you could pass some sort of 'calculation state'
// object through the recursive calls and evaluate the violation
// through that object if the current node is insufficient
if(this.headIsViolation()) {
// Terminate the recursion
return true;
}
// Fortunately, Java short-circuits ||
// So if the left child is in violation, the right child will
// not even be checked
return this.getLeft().checkViolation() || this.getRight().checkViolation();
}
}
I'd recommend an exception handling. That makes clear, that the recursion was aborted because of some violation (or other exception):
public void outer() {
try {
int i = recurse(0);
} catch (OuchException ouch) {
// handle the exception here
}
}
private int recurse(int i) throws OuchException {
// for tree-like structures
if (thisIsALeaf) {
return i;
}
// the violation test
if (itHurts)
throw new OuchException("That really hurts");
// we also can encapsulate other exceptions
try {
someMethod();
} catch (Exception oops) {
throw new OuchException(oops);
}
// recurse
return recurse(i++);
}
Sure, it violates the initial requirement to return 'true' upon abortion. But I prefer a clean separation of return values and notification on abnormal behaviour.
If it's a single thread doing the recursion you could throw an exception. Bit ugly though - kind of using an exception as a goto.
boolean myPublicWrapperMethod(...) {
try {
return myPrivateRecursiveFunction(...);
} catch (MySpecificException e) {
return true;
}
}
A better approach would be to eliminate the recursion and use a Stack collection holding a class representing what would have been recursive state, iterate in a loop and just return true when you want.