Can anybody suggest programming examples that illustrate recursive functions? There are the usual old horses such as Fibonacci series and Towers of Hanoi, but anything besides them would be fun.
-
11See my comment on this question: http://stackoverflow.com/questions/126756/examples-of-recursive-functions – DutGRIFF Mar 11 '14 at 02:36
22 Answers
This illustration is in English, rather than an actual programming language, but is useful for explaining the process in a non-technical way:
A child couldn't sleep, so her mother told a story about a little frog, who couldn't sleep, so the frog's mother told a story about a little bear, who couldn't sleep, so bear's mother told a story about a little weasel ...who fell asleep. ...and the little bear fell asleep; ...and the little frog fell asleep; ...and the child fell asleep.

- 40,958
- 16
- 80
- 86
-
1
-
17@Joachim Weasel is always the base case, dude. _You know this!_ – Andres Jaan Tack May 04 '10 at 11:57
-
5
-
1
-
12
-
In order to understand recursion, one must first understand recursion.

- 1
- 1

- 11,782
- 1
- 40
- 50
The rule of thumb for recursion is, "Use recursion, if and only if on each iteration your task splits into two or more similar tasks".
So Fibonacci is not a good example of recursion application, while Hanoi is a good one.
So most of the good examples of recursion are tree traversal in different disquises.
For example: graph traversal - the requirement that visited node will never be visited again effectively makes graph a tree (a tree is a connected graph without simple cycles)
divide and conquer algorithms (quick sort, merge sort) - parts after "divide" constitute children nodes, "conquer" constitues edges from parent node to child nodes.

- 1,623
- 16
- 21
-
4
-
1
-
1
-
To elaborate on why the first sentence is so key. Imagine the opposite case. If the task doesn't split into multiple paths, you can just simply use iteration. Google Fibonacci iteration vs recursion. The iteration version is way faster, memory efficient, and won't overflow the stack. So you only use recursion... when you need/benefit enough to surpass the additional drawbacks of using recursion. – Katastic Voyage Jan 20 '18 at 01:48
How about testing a string for being a palindrome?
bool isPalindrome(char* s, int len)
{
if(len < 2)
return TRUE;
else
return s[0] == s[len-1] && isPalindrome(&s[1], len-2);
}
Of course, you could do that with a loop more efficiently.

- 107,154
- 87
- 232
- 265
-
2Why provide a bad example of recursion and criticize over people over the same thing? – Kaerber Feb 27 '13 at 11:26
-
@Kaerber I didn't criticize anyone. I stated on Yuval's answer (and on my own) that they are examples that are better done with a loop. – Kip Feb 27 '13 at 16:58
-
1@Kip @Kaerber, not necessarily bad if we use compile time evaluation . . . . `constexpr bool compileTimeIsPalindrome(const char* s, int len) { return len < 2 ? true : s[0] == s[len-1] && compileTimeIsPalindrome(&s[1], len-2); }` ;-) – learnvst Mar 04 '14 at 18:34
From the world of math, there is the Ackermann function:
Ackermann(m, n)
{
if(m==0)
return n+1;
else if(m>0 && n==0)
return Ackermann(m-1, 1);
else if(m>0 && n>0)
return Ackermann(m-1, Ackermann(m, n-1));
else
throw exception; //not defined for negative m or n
}
It always terminates, but it produces extremely large results even for very small inputs. Ackermann(4, 2), for example, returns 265536 − 3.

- 107,154
- 87
- 232
- 265
-
2`if (m > 0 && n == 0)` it should return `Ackermann(m - 1, 1)` not `Ackermann(m - 1, n)` (which is `Ackermann(m - 1, 0)`). At least according to Wikipedia, which you cited. – monkey0506 Nov 27 '13 at 17:28
-
2
-
1Hey, they get the best of us. ;) Just clarifying for posterity's sake. – monkey0506 Dec 02 '13 at 04:29
The interpreter design pattern is a quite nice example because many people don't spot the recursion. The example code listed in the Wikipedia article illustrates well how this can be applied. However, a much more basic approach that still implements the interpreter pattern is a ToString
function for nested lists:
class List {
public List(params object[] items) {
foreach (object o in items)
this.Add(o);
}
// Most of the implementation omitted …
public override string ToString() {
var ret = new StringBuilder();
ret.Append("( ");
foreach (object o in this) {
ret.Append(o);
ret.Append(" ");
}
ret.Append(")");
return ret.ToString();
}
}
var lst = new List(1, 2, new List(3, 4), new List(new List(5), 6), 7);
Console.WriteLine(lst);
// yields:
// ( 1 2 ( 3 4 ) ( ( 5 ) 6 ) 7 )
(Yes, I know it's not easy to spot the interpreter pattern in the above code if you expect a function called Eval
… but really, the interpreter pattern doesn't tell us what the function is called or even what it does and the GoF book explicitly lists the above as an example of said pattern.)

- 530,221
- 131
- 937
- 1,214
-
Interestingly, *any* iteration can be expressed as a `fold` and `fold` can in turn be interpreted (pun intended) as a parametrizable interpreter for a programming language with just two commands `element(e)` and `NIL`, where the list is the program. Cool, huh? Found that interpretation here: [Functional Programming for Beginners - Rúnar Óli Bjarnason - Boston Area Scala Enthusiasts](http://vimeo.com/18554216/). – Jörg W Mittag Oct 08 '11 at 16:16
-
Nested lists are in fact a quick, dirty and inefficient tree, no wonder that recursion fits them well. – Kaerber Feb 27 '13 at 11:30
-
@Kaerber I don’t understand the conclusion of that comment. I also agree with its premise: nested lists are trees, true. They are neither quick, nor dirty, nor inefficient. They are simply *one* way of implementing a general tree that is sometimes (but admittedly not very often) appropriate. – Konrad Rudolph Feb 27 '13 at 11:34
-
Sorry, I haven't thought it through. Nested lists are in fact efficient (and one of the canonical) implementations of the tree. The conclusion was based on two hidden premises that 1) the sole good use of recursion is traversing a tree, 2) string representation of a tree requires traversing it, and stated one, 3) nested lists are trees. So the argument concludes that yes, in fact, recursion is appropriate/efficient for toString function on nested lists. – Kaerber Feb 27 '13 at 16:17
In my opinion, recursion is good to know, but most solutions that could use recursion could also be done using iteration, and iteration is by far more efficient.
That said here is a recursive way to find a control in a nested tree (such as ASP.NET or Winforms):
public Control FindControl(Control startControl, string id)
{
if (startControl.Id == id)
return startControl
if (startControl.Children.Count > 0)
{
foreach (Control c in startControl.Children)
{
return FindControl(c, id);
}
}
return null;
}

- 172,459
- 74
- 246
- 311
-
3“and iteration is by far more efficient” -- such blanket statements are almost always false (yet another one ;-)). Use tail recursion and performance is on par with iteration. – Konrad Rudolph Sep 24 '08 at 14:19
-
Proponents of functional programming seem to prefer recursion whenever possible, and use the fact that tail recursion == iteration as an excuse. In the real world, recursion comes at a cost. – Marcus Downing Sep 24 '08 at 16:09
-
holy! how did you get code off my development box? That is almost exactly character by character and even line spacing, a function i have in my own library. – stephenbayer Sep 24 '08 at 16:36
-
stephen, I think we've all written that function more than once :) Konrad, even tail recursion has the added cost of pushing the function arguments to the stack once. – FlySwat Sep 24 '08 at 17:09
-
Jon, even iteration, when encapsulated in a function, “has the added cost of pushing the function arguments to the stack once.” So there. Additionally, there's function call inlining which also works for tail recursive functions. – Konrad Rudolph Sep 25 '08 at 08:47
-
Not every compiler will do tail call optimizations, and your assuming that the iteration has been placed in a secondary function to begin with, what about iterating in a function instead of calling out to as second function to do recursion? No matter how you slice it, iteration is more efficient. – FlySwat Sep 25 '08 at 16:02
-
Iteration is far less efficient when you have several similar branches in your code. For a good example, try rewriting your own example into the loop form. It's possible, but it's absolutely not trivial, and is quite hard to get right. – Kaerber Feb 27 '13 at 11:28
Here's a pragmatic example from the world of filesystems. This utility recursively counts files under a specified directory. (I don't remember why, but I actually had a need for something like this long ago...)
public static int countFiles(File f) {
if (f.isFile()){
return 1;
}
// Count children & recurse into subdirs:
int count = 0;
File[] files = f.listFiles();
for (File fileOrDir : files) {
count += countFiles(fileOrDir);
}
return count;
}
(Note that in Java a File
instance can represent either a normal file or a directory. This utility excludes directories from the count.)
A common real world example would be e.g. FileUtils.deleteDirectory()
from the Commons IO library; see the API doc & source.

- 80,077
- 70
- 264
- 372
A real-world example is the "bill-of-materials costing" problem.
Suppose we have a manufacturing company that makes final products. Each product is describable by a list of its parts and the time required to assemble those parts. For example, we manufacture hand-held electric drills from a case, motor, chuck, switch, and cord, and it takes 5 minutes.
Given a standard labor cost per minute, how much does it cost to manufacture each of our products?
Oh, by the way, some parts (e.g. the cord) are purchased, so we know their cost directly.
But we actually manufacture some of the parts ourselves. We make a motor out of a housing, a stator, a rotor, a shaft, and bearings, and it takes 15 minutes.
And we make the stator and rotor out of stampings and wire, ...
So, determining the cost of a finished product actually amounts to traversing the tree that represents all whole-to-list-of-parts relationships in our processes. That is nicely expressed with a recursive algorithm. It can certainly be done iteratively as well, but the core idea gets mixed in with the do-it-yourself bookkeeping, so it's not as clear what's going on.

- 30,725
- 9
- 56
- 64
The hairiest example I know is Knuth's Man or Boy Test. As well as recursion it uses the Algol features of nested function definitions (closures), function references and constant/function dualism (call by name).

- 6,509
- 1
- 34
- 44
As others have already said, a lot of canonical recursion examples are academic.
Some practical uses I 've encountered in the past are:
1 - Navigating a tree structure, such as a file system or the registry
2 - Manipulating container controls which may contain other container controls (like Panels or GroupBoxes)

- 57,317
- 63
- 160
- 234
My personal favorite is Binary Search
Edit: Also, tree-traversal. Walking down a folder file structure for instance.

- 9,340
- 7
- 38
- 48
-
1Binary search is not a good example of recursion, and its implementation as a loop is much more efficiet. – Kaerber Feb 27 '13 at 11:22
-
It is a good example of recursion *because* it is so easily compared to a loop. Anyone learning recursive programming can see how the two algorithms relate. And if binary search is implemented properly with tail recursion, the compilers can make them just as efficient as if you programmed a loop. – Geoff Mar 28 '13 at 12:57
Implementing Graphs by Guido van Rossum has some recursive functions in Python to find paths between two nodes in graphs.

- 3,648
- 1
- 19
- 15
My favorite sort, Merge Sort
(Favorite since I can remember the algorithm and is it not too bad performance-wise)

- 28,043
- 9
- 61
- 79
-
Merge sort is awesome :) ... and also one of the few algorithms I actually remember ! – anbanm Sep 24 '08 at 12:23
- Factorial
- Traversing a tree in depth (in a filesystem, a game space, or any other case)

- 330,807
- 53
- 334
- 373
-
Actually, factorial is often better done using a loop. It's kind of a stupid, tho often used, example – Rik Sep 24 '08 at 12:36
-
It may perfrom better in a loop, but it is a well understood idea that easily expressed rescursively especially in languages with partial functions. – Steve g Sep 24 '08 at 13:13
-
1So many common examples are actually loop-like, simply because the people who use functional languages seem to prefer recursion. In 'normal' programming languages, most things are better done as a loop, both for performance and for readable code. – Marcus Downing Sep 24 '08 at 16:04
-
I think, it's easier to teach recursion this way, because the best use cases for recursion - divide and conquer style algorithms - are of significantly higher complexety than recursion itself. – Kaerber Feb 27 '13 at 11:07
How about reversing a string?
void rev(string s) {
if (!s.empty()) {
rev(s[1..s.length]);
}
print(s[0]);
}
Understanding this helps understand recursion.

- 20,565
- 5
- 44
- 69
-
1
-
Sure it is, but this question requested examples to illustrate recursion, and this example adds something not found in other examples. – Yuval F Dec 02 '08 at 07:24
-
Well, as they say, if you can't be a good example, be a horrible warning. – Kaerber Feb 27 '13 at 11:35
How about anything processing lists, like:
- map (and andmap, ormap)
- fold (foldl, foldr)
- filter
- etc...

- 36,513
- 30
- 103
- 141
Once upon a time, and not that long ago, elementary school children learned recursion using Logo and Turtle Graphics. http://en.wikipedia.org/wiki/Turtle_graphics
Recursion is also great for solving puzzles by exhaustive trial. There is a kind of puzzle called a "fill in" (Google it) in which you get a grid like a crossword, and the words, but no clues, no numbered squares. I once wrote a program using recursion for a puzzle publisher to solve the puzzles in order be sure the known solution was unique.

- 4,182
- 5
- 32
- 30
Recursive functions are great for working with recursively defined datatypes:
- A natural number is zero or the successor of another natural number
- A list is the empty list or another list with an element in front
- A tree is a node with some data and zero or more other subtrees
Etc.

- 45,466
- 8
- 54
- 65
-
The only thing worth doing a recursion over is a tree. Other datatypes can also be defined inductively instead of recursively (i.e. empty list is a list, list with one element is a list, if a list with n-1 elements is a list, then a list with n elements is a list), which suggests that the loop will be more efficient. – Kaerber Feb 27 '13 at 11:11
Translate a spreadsheet column index to a column name.
It's trickier than it sounds, because spreadsheet columns don't handle the '0' digit properly. For example, if you take A-Z as digits when you increment from Z to AA it would be like going from 9 to 11 or 9 to 00 instead of 10 (depending on whether A is 1 or 0). Even the Microsoft Support example gets it wrong for anything higher than AAA!
The recursive solution works because you can recurse right on those new-digit boundries. This implementation is in VB.Net, and treats the first column ('A') as index 1.
Function ColumnName(ByVal index As Integer) As String
Static chars() As Char = {"A"c, "B"c, "C"c, "D"c, "E"c, "F"c, "G"c, "H"c, "I"c, "J"c, "K"c, "L"c, "M"c, "N"c, "O"c, "P"c, "Q"c, "R"c, "S"c, "T"c, "U"c, "V"c, "W"c, "X"c, "Y"c, "Z"c}
index -= 1 'adjust index so it matches 0-indexed array rather than 1-indexed column'
Dim quotient As Integer = index \ 26 'normal / operator rounds. \ does integer division'
If quotient > 0 Then
Return ColumnName(quotient) & chars(index Mod 26)
Else
Return chars(index Mod 26)
End If
End Function

- 399,467
- 113
- 570
- 794