First off, I'd like to say that I'm looking for more than just a tutorial on this one. I'd like to ask anyone who reads this to try to contribute with their own recursive methods, to use as an example, and also to discuss the benefits and disadvantages of recursion.
Recursion is a very interesting topic in programming. It takes a bit of practice to get used to it, so I'm going to include a few examples, written in C#, C++ and Java. Hopefully, they'll apply to you, but I'm adding pseudocode for those of you who specialise in other languages.
First, a little Q&A
WTF is recursion?
Recursion is a really neat way to write your functions. A simple definition of recursion would be this:
A recursive function is one which calls itself.
Basically, if you've ever written a function that called itself~ you were using recursion!
So, what are the benefits of using recursion?
Well, after you get a little used to using recursion, the key design benefits are:
- Code is clearer and easier to use
- The code can be much shorter, and easier to read
The greatest and most common example of where recursion really comes in handy is listing the contents of directories, sub directories, sub sub directories, etc. I'll be demonstrating how this can be done later, when we come to the examples.
Well, this recursion lark sounds pretty cool. What are the drawbacks?
As with anything in life, there are drawbacks, along with the benefits. These include:
- It can be hard to find bugs~ particularly when using global variables
- It takes quite a bit of practice to get used to
- Space~ not too big a problem in modern technology, but any local variables within the function have to be created over and over again
- Time~ the operations which affect the space often affect the time of the method
So, without further ado, let's get down to an example! This is a method to print a triangle in the console. Admittedly, it's not the most interesting method, but it's a simple demonstration of recursion. I'll write this in pseudocode, and follow it up with examples in C++ and Java.
void recursiveTriangle(int x) { // the function name, return type, and parameters. Nothing new here
if (x == 0) return; // there's nothing left to print
for (int i = 0; i < x; i++) // start a loop to print the stars for this row
print a star // print a star for this line
print a new line character // end of the line, get ready for the next!
recursiveTriangle(--x); // call the method again, with one less star to print on the row
}
So, for example, if we called this method like so: recursiveTriangle(4), the output would be:****
***
**
*
So why is this? It's time to look at the structure, and see how this works:
First call, pass 4 (call #1)
...print 4 stars
...print a new line
...call self: recursiveTriangle(3) (call #2)
......print 3 stars
......print a new line
......call self: recursiveTriangle(2) (call #3)
.........print 2 stars
.........print a new line
.........call self: recursiveTriangle(1) (call #4)
............print 1 star
............print a new line
............call self: recursiveTriangle(0) (call #5)
...............Oh! it's 0!
............end call #5
.........end call #4
......end call #3
...end call #2
end call #1
Notice the hierarchical stucture, which I mentioned earlier? It's very systematic, isn't it?
As promised, here are the examples.
C++
void recursiveTriangle(int x) {
if (x == 0) return; // do nothing else
for (int i = 0; i < x; i++)
cout << "*";
cout << endl;
recursiveTriangle(--x);
}
Java
public static void recursiveTriangle(int x) {
if (x == 0) return; // do nothing else
for (int i = 0; i < x; i++)
System.out.print("*");
System.out.print("\n");
recursiveTriangle(--x);
}
Lastly, let's take a look at populating a TreeViews with the contents of directories, sub directories, files, etc.
Java
Note that I've also added a Boolean "recursive" so that the method can be used to scan either just one level, or all levels~
/*
* @params: String directory ~ the directory to scan
* @params: DefaultMutableTreeNode parent ~ the node to add any files as children
* @params: Boolean recursive ~ determine whether to scan all subdirectories, or just the parent
*/
public static void listAllFiles(String directory, DefaultMutableTreeNode parent, Boolean recursive) {
File [] children = new File(directory).listFiles(); // list all the files in the directory
for (int i = 0; i < children.length; i++) { // loop through each
DefaultMutableTreeNode node = new DefaultMutableTreeNode(children[i].getName());
// only display the node if it isn't a folder, and if this is a recursive call
if (children[i].isDirectory() && recursive) {
parent.add(node); // add as a child node
listAllFiles(children[i].getPath(), node, recursive); // call again for the subdirectory
} else if (!children[i].isDirectory()){ // otherwise, if it isn't a directory
parent.add(node); // add it as a node and do nothing else
}
}
}
C#
/// <summary>
/// A method to populate a TreeView with directories, subdirectories, etc
/// </summary>
/// <param name="dir">The path of the directory</param>
/// <param name="node">The "master" node, to populate</param>
public void PopulateTree(string dir, TreeNode node) {
// get the information of the directory
DirectoryInfo directory = new DirectoryInfo(dir);
// loop through each subdirectory
foreach(DirectoryInfo d in directory.GetDirectories()) {
// create a new node
TreeNode t = new TreeNode(d.Name);
// populate the new node recursively
PopulateTree(d.FullName, t);
node.Nodes.Add(t); // add the node to the "master" node
}
// lastly, loop through each file in the directory, and add these as nodes
foreach(FileInfo f in directory.GetFiles()) {
// create a new node
TreeNode t = new TreeNode(f.Name);
// add it to the "master"
node.Nodes.Add(t);
}
}
I'm hoping to get a few more examples written, and hopefully others will contribute~ It might not be much, but any examples posted, I'll click that "This post was helpful" link to thank you.








MultiQuote









|