From Wikipedia:
Recursion in computer science is a method where the solution to a problem depends on solutions to smaller instances of the same problem (as opposed to iteration). The approach can be applied to many types of problems, and recursion is one of the central ideas of computer science.
Recursion is a great tool to know how to use in programming. It's main idea is to break down a large hard to process idea or action into smaller more digestible ideas or actions. While sorting is a good example of recursion, I'd like to present to you my favorite example of recursion, recursive string matching.
If you have a key you're matching your string to which includes wild cards, recursion is a good way to break up the potential matches into a easier to match problem.
If we have a key of a*b?c (where * can represent any number of characters and ? is any single character) and we want to check azyxbwc to see if they fit the key the process is pretty simple once you get the hang of it (I'll be writing a rough psuedo-code for the example).
Enter Function with key='a*b?c' and input='azyxbwc'
Retrieve first letter of key --> 'a'
Retrieve first letter of input --> 'a'
Does 'a' == 'a' --> true
If true, call function with remaining key & input
Enter Function with key='*b?c' and input='zyxbwc'
Retrieve first letter of key --> '*'
Retrieve second letter of key --> 'b' //if first is a wildcard, get a second
Retrieve first letter of input --> 'z'
Does '*' == 'z' --> false
Does 'b' == 'z' --> false
Is '*' a wildcard --> true
If true, call function with remaining key & input //key keeps wild b/c second letter didn't match
Enter Function with key='*b?c' and input='yxbwc'
Retrieve first letter of key --> '*'
Retrieve second letter of key --> 'b' //if first is a wildcard, get a second
Retrieve first letter of input --> 'y'
Does '*' == 'y' --> false
Does 'b' == 'y' --> false
Is '*' a wildcard --> true
If true, call function with remaining key & input
Enter Function with key='*b?c' and input='xbwc'
Retrieve first letter of key --> '*'
Retrieve second letter of key --> 'b' //if first is a wildcard, get a second
Retrieve first letter of input --> 'x'
Does '*' == 'x' --> false
Does 'b' == 'x' --> false
Is '*' a wildcard --> true
If true, call function with remaining key & input
Enter Function with key='*b?c' and input='bwc'
Retrieve first letter of key --> '*'
Retrieve second letter of key --> 'b' //if first is a wildcard, get a second
Retrieve first letter of input --> 'b'
Does '*' == 'x' --> false
Does 'b' == 'b' --> true
If true, call function with remaining key & input //when you match the letter after the wildcard you send the key with both the wildcard and matching letter removed
//Also, a key note here, in more complex cases, you may need to keep iterating on the wildcard even after the first match for the following letter is found
Enter Function with key='?c' and input='wc'
Retrieve first letter of key --> '?'
Retrieve first letter of input --> 'w'
If true, call function with remaining key & input // I've defined ? to match any single character, it just goes through with removing the a letter from key and input
Enter Function with key='c' and input='c'
Retrieve first letter of key --> 'c'
Retrieve first letter of input --> 'c'
Does 'c' == 'c' --> true
If true, call function with remaining key & input
Enter Function with key='' and input=''
Return true
Sorry for the huge example, but for really getting the idea of recursion I think it's important. You'll notice, every step my 'input' got smaller, putting me one step closer to solving my problem. That's the whole idea behind recursion.
Now on to sorting by recursion. I prefer the bubble sort, so that's what I've chosen to show here today. A bubble sort is neat because it's implemented with both recursion and iteration. Here's my example:
public class test {
public static void main (String[] args) {
int[] a = {1,4,2,2,1};
a = sort(a);
for (int i = 0; i < a.length; i++) {
System.out.println("" + a[i]);
}
}
public static int[] sort(int[] a) {
int temp;
boolean sorted = true;
int[] ret = a;
for (int i = 0; i < a.length - 1; i++) {
if (ret[i] > ret[i+1]) {
temp = ret[i];
ret[i] = ret[i+1];
ret[i+1] = temp;
sorted = false;
}
}
if (sorted) {
return ret;
} else {
return sort(ret);
}
}
}
Let's take a look at what's going on here:
- We start with our array at
1,4,2,2,1.
- After the first time through our sort function we end up with
1,2,2,1,4.
- We changed the ordering (so we're not sorted), and we have to call the function again.
- Second time in we have
1,2,2,1,4 and we end up with 1,2,1,2,4.
- We changed the ordering (so we're not sorted), and we have to call the function again.
- Third time in we have
1,2,1,2,4 and we end up with 1,1,2,2,4.
- We changed the ordering (so we're not sorted), and we have to call the function again.
- Fourth time in we have
1,1,2,2,4 and we end up with 1,1,2,2,4.
- We didn't change the order (we're sorted!). Return the sorted array.
I hope that this helped you out in your quest for understanding recursion. Please feel free to write comments if you would like further clarification on something I mentioned.